static char *getModuleEntry(EspRoute *eroute, cchar *kind, cchar *source, cchar *cacheName) { char *cp, *entry; if (smatch(kind, "view")) { entry = sfmt("esp_%s", cacheName); } else if (smatch(kind, "app")) { if (eroute->combine) { entry = sfmt("esp_%s_%s_combine", kind, eroute->appName); } else { entry = sfmt("esp_%s_%s", kind, eroute->appName); } } else { /* Controller */ if (eroute->appName) { entry = sfmt("esp_%s_%s_%s", kind, eroute->appName, mprTrimPathExt(mprGetPathBase(source))); } else { entry = sfmt("esp_%s_%s", kind, mprTrimPathExt(mprGetPathBase(source))); } } for (cp = entry; *cp; cp++) { if (!isalnum((uchar) *cp) && *cp != '_') { *cp = '_'; } } return entry; }
/* Set the Uri extension static function set extension(ext: String?): Void */ static EjsObj *uri_set_extension(Ejs *ejs, EjsUri *up, int argc, EjsObj **argv) { HttpUri *uri; uri = up->uri; if (argv[0] == ESV(null)) { uri->ext = 0; uri->path = mprTrimPathExt(uri->path); } else { uri->ext = ejsToMulti(ejs, argv[0]); uri->path = sjoin(mprTrimPathExt(uri->path), uri->ext, NULL); } return 0; }
/* Replace the Uri extension static function set replaceExt(ext: String): Uri */ static EjsUri *uri_replaceExtension(Ejs *ejs, EjsUri *up, int argc, EjsObj **argv) { EjsUri *np; HttpUri *nuri; char *ext; np = cloneUri(ejs, up, 1); nuri = np->uri; nuri->path = mprTrimPathExt(nuri->path); ext = ejsToMulti(ejs, argv[0]); if (ext && *ext == '.') { ext++; } nuri->ext = ext; nuri->path = sjoin(mprTrimPathExt(nuri->path), ".", nuri->ext, NULL); return np; }
/* Start the command to run (stdIn and stdOut are named from the client's perspective) */ PUBLIC int startProcess(MprCmd *cmd) { MprCmdTaskFn entryFn; MprModule *mp; char *entryPoint, *program, *pair; int pri, next; mprLog("info mpr cmd", 4, "Program %s", cmd->program); entryPoint = 0; if (cmd->env) { for (ITERATE_ITEMS(cmd->env, pair, next)) { if (sncmp(pair, "entryPoint=", 11) == 0) { entryPoint = sclone(&pair[11]); } } } program = mprGetPathBase(cmd->program); if (entryPoint == 0) { program = mprTrimPathExt(program); entryPoint = program; } #if ME_CPU_ARCH == MPR_CPU_IX86 || ME_CPU_ARCH == MPR_CPU_IX64 || ME_CPU_ARCH == MPR_CPU_SH /* A leading underscore is required on some architectures */ entryPoint = sjoin("_", entryPoint, NULL); #endif if (mprFindVxSym(sysSymTbl, entryPoint, (char**) (void*) &entryFn) < 0) { if ((mp = mprCreateModule(cmd->program, cmd->program, NULL, NULL)) == 0) { mprLog("error mpr cmd", 0, "Cannot create module"); return MPR_ERR_CANT_CREATE; } if (mprLoadModule(mp) < 0) { mprLog("error mpr cmd", 0, "Cannot load DLL %s, errno %d", program, mprGetOsError()); return MPR_ERR_CANT_READ; } if (mprFindVxSym(sysSymTbl, entryPoint, (char**) (void*) &entryFn) < 0) { mprLog("error mpr cmd", 0, "Cannot find symbol %s, errno %d", entryPoint, mprGetOsError()); return MPR_ERR_CANT_ACCESS; } } taskPriorityGet(taskIdSelf(), &pri); cmd->pid = taskSpawn(entryPoint, pri, VX_FP_TASK | VX_PRIVATE_ENV, ME_STACK_SIZE, (FUNCPTR) cmdTaskEntry, (int) cmd->program, (int) entryFn, (int) cmd, 0, 0, 0, 0, 0, 0, 0); if (cmd->pid < 0) { mprLog("error mpr cmd", 0, "Cannot create task %s, errno %d", entryPoint, mprGetOsError()); return MPR_ERR_CANT_CREATE; } if (semTake(cmd->startCond, MPR_TIMEOUT_START_TASK) != OK) { mprLog("error mpr cmd", 0, "Child %s did not initialize, errno %d", cmd->program, mprGetOsError()); return MPR_ERR_CANT_CREATE; } semDelete(cmd->startCond); cmd->startCond = 0; return 0; }
/* function trimExt(): Uri */ static EjsUri *uri_trimExt(Ejs *ejs, EjsUri *up, int argc, EjsObj **argv) { EjsUri *np; HttpUri *nuri; np = cloneUri(ejs, up, 1); nuri = np->uri; nuri->ext = 0; nuri->path = mprTrimPathExt(nuri->path); return np; }
/* Tokens: ARCH Build architecture (x86_64) CC Compiler (cc) DEBUG Debug compilation options (-g, -Zi -Od) INC Include directory out/inc LIB Library directory (out/lib, xcode/VS: out/bin) LIBS Libraries required to link with ESP OBJ Name of compiled source (out/lib/view-MD5.o) OUT Output module (view_MD5.dylib) SHLIB Host Shared library (.lib, .so) SHOBJ Host Shared Object (.dll, .so) SRC Source code for view or controller (already templated) TMP Temp directory VS Visual Studio directory WINSDK Windows SDK directory */ char *espExpandCommand(cchar *command, cchar *source, cchar *module) { MprBuf *buf; MaAppweb *appweb; cchar *cp, *out; char *tmp; #if BLD_WIN_LIKE cchar *path; path = 0; #endif if (command == 0) { return 0; } out = mprTrimPathExt(module); buf = mprCreateBuf(-1, -1); appweb = MPR->appwebService; for (cp = command; *cp; ) { if (*cp == '$') { if (matchToken(&cp, "${ARCH}")) { /* Build architecture */ mprPutStringToBuf(buf, appweb->hostArch); #if BLD_WIN_LIKE } else if (matchToken(&cp, "${WINSDK}")) { path = mprReadRegistry("HKLM\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows", "CurrentInstallFolder"); path = strim(path, "\\", MPR_TRIM_END); mprPutStringToBuf(buf, path); } else if (matchToken(&cp, "${VS}")) { path = mprGetPathParent(mprGetPathParent(getenv("VS100COMNTOOLS"))); mprPutStringToBuf(buf, mprGetPortablePath(path)); #endif } else if (matchToken(&cp, "${CC}")) { /* Compiler */ #if BLD_WIN_LIKE // MOB - what about cross compilation path = mprJoinPath(mprGetPathParent(mprGetPathParent(getenv("VS100COMNTOOLS"))), "VC/bin/cl.exe"); mprPutStringToBuf(buf, mprGetPortablePath(path)); #else mprPutStringToBuf(buf, BLD_CC); #endif } else if (matchToken(&cp, "${DEBUG}")) { mprPutStringToBuf(buf, ESP_DEBUG); } else if (matchToken(&cp, "${INC}")) { /* Include directory (out/inc) */ mprPutStringToBuf(buf, mprResolvePath(mprGetAppDir(), "inc")); } else if (matchToken(&cp, "${LIB}")) { /* Library directory. IDE's use bin dir */ mprPutStringToBuf(buf, getOutDir(BLD_LIB_NAME)); } else if (matchToken(&cp, "${LIBS}")) { /* Required libraries to link. These may have nested ${TOKENS} */ mprPutStringToBuf(buf, espExpandCommand(ESP_LIBS, source, module)); } else if (matchToken(&cp, "${OBJ}")) { /* Output object with extension (.o) */ mprPutStringToBuf(buf, mprJoinPathExt(out, BLD_OBJ)); } else if (matchToken(&cp, "${OUT}")) { /* Output modules */ mprPutStringToBuf(buf, out); } else if (matchToken(&cp, "${SHLIB}")) { /* .lib */ mprPutStringToBuf(buf, appweb->hostOs); } else if (matchToken(&cp, "${SHOBJ}")) { /* .dll */ #ifdef BLD_HOST_SHOBJ // MOB - need this for bit mprPutStringToBuf(buf, BLD_HOST_SHOBJ); #else mprPutStringToBuf(buf, BLD_SHOBJ); #endif } else if (matchToken(&cp, "${SRC}")) { /* View (already parsed into C code) or controller source */ mprPutStringToBuf(buf, source); } else if (matchToken(&cp, "${TMP}")) { #if BLD_WIN_LIKE if ((tmp = getenv("TMP")) == 0) { tmp = getenv("TEMP"); } #else tmp = getenv("TMPDIR"); #endif mprPutStringToBuf(buf, tmp ? tmp : "."); #ifdef WIND_BASE } else if (matchToken(&cp, "${WIND_BASE}")) { mprPutStringToBuf(buf, WIND_BASE); #endif #ifdef WIND_HOME } else if (matchToken(&cp, "${WIND_HOME}")) { mprPutStringToBuf(buf, WIND_HOME); #endif #ifdef WIND_HOST_TYPE } else if (matchToken(&cp, "${WIND_HOST_TYPE}")) { mprPutStringToBuf(buf, WIND_HOST_TYPE); #endif #ifdef WIND_PLATFORM } else if (matchToken(&cp, "${WIND_PLATFORM}")) { mprPutStringToBuf(buf, WIND_PLATFORM); #endif #ifdef WIND_GNU_PATH } else if (matchToken(&cp, "${WIND_GNU_PATH}")) { mprPutStringToBuf(buf, WIND_GNU_PATH); #endif } else { mprPutCharToBuf(buf, *cp++); } } else { mprPutCharToBuf(buf, *cp++); } } mprAddNullToBuf(buf); return sclone(mprGetBufStart(buf)); }
/* Compile a view or controller cacheName MD5 cache name (not a full path) source ESP source file name module Module file name */ bool espCompile(HttpConn *conn, cchar *source, cchar *module, cchar *cacheName, int isView) { MprFile *fp; HttpRx *rx; HttpRoute *route; EspRoute *eroute; cchar *csource; char *layout, *script, *page, *err; ssize len; rx = conn->rx; route = rx->route; eroute = route->eroute; layout = 0; if (isView) { if ((page = mprReadPathContents(source, &len)) == 0) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't read %s", source); return 0; } /* Use layouts iff there is a source defined on the route. Only MVC/controllers based apps do this. */ if (eroute->layoutsDir) { #if UNUSED layout = mprSamePath(eroute->layoutsDir, route->dir) ? 0 : mprJoinPath(eroute->layoutsDir, "default.esp"); #else layout = mprJoinPath(eroute->layoutsDir, "default.esp"); #endif } if ((script = espBuildScript(route, page, source, cacheName, layout, &err)) == 0) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't build %s, error %s", source, err); return 0; } csource = mprJoinPathExt(mprTrimPathExt(module), ".c"); if ((fp = mprOpenFile(csource, O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0664)) == 0) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't open compiled script file %s", csource); return 0; } len = slen(script); if (mprWriteFile(fp, script, len) != len) { httpError(conn, HTTP_CODE_INTERNAL_SERVER_ERROR, "Can't write compiled script file %s", csource); mprCloseFile(fp); return 0; } mprCloseFile(fp); } else { csource = source; } mprMakeDir(eroute->cacheDir, 0775, -1, -1, 1); /* WARNING: GC yield here */ if (runCommand(conn, eroute->compile, csource, module) < 0) { return 0; } if (eroute->link) { /* WARNING: GC yield here */ if (runCommand(conn, eroute->link, csource, module) < 0) { return 0; } #if !(BLD_DEBUG && MACOSX) /* MAC needs the object for debug information */ mprDeletePath(mprJoinPathExt(mprTrimPathExt(module), BLD_OBJ)); #endif } #if BLD_WIN_LIKE { /* Windows leaves intermediate object in the current directory */ cchar *obj; obj = mprReplacePathExt(mprGetPathBase(csource), BLD_OBJ); if (mprPathExists(obj, F_OK)) { mprDeletePath(obj); } } #endif if (!eroute->keepSource && isView) { mprDeletePath(csource); } return 1; }
/* Tokens: ARCH Build architecture (64) GCC_ARCH ARCH mapped to gcc -arch switches (x86_64) CC Compiler (cc) DEBUG Debug compilation options (-g, -Zi -Od) INC Include directory out/inc LIB Library directory (out/lib, xcode/VS: out/bin) LIBS Libraries required to link with ESP OBJ Name of compiled source (out/lib/view-MD5.o) MOD Output module (view_MD5.dylib) SHLIB Host Shared library (.lib, .so) SHOBJ Host Shared Object (.dll, .so) SRC Source code for view or controller (already templated) TMP Temp directory VS Visual Studio directory WINSDK Windows SDK directory */ PUBLIC char *espExpandCommand(EspRoute *eroute, cchar *command, cchar *source, cchar *module) { MprBuf *buf; MaAppweb *appweb; cchar *cp, *outputModule, *os, *arch, *profile; char *tmp; if (command == 0) { return 0; } appweb = MPR->appwebService; outputModule = mprTrimPathExt(module); maParsePlatform(appweb->platform, &os, &arch, &profile); buf = mprCreateBuf(-1, -1); for (cp = command; *cp; ) { if (*cp == '$') { if (matchToken(&cp, "${ARCH}")) { /* Target architecture (x86|mips|arm|x64) */ mprPutStringToBuf(buf, arch); } else if (matchToken(&cp, "${GCC_ARCH}")) { /* Target architecture mapped to GCC mtune|mcpu values */ mprPutStringToBuf(buf, getMappedArch(arch)); } else if (matchToken(&cp, "${INC}")) { /* Include directory for the configuration */ mprPutStringToBuf(buf, mprJoinPath(appweb->platformDir, "inc")); } else if (matchToken(&cp, "${LIBPATH}")) { /* Library directory for Appweb libraries for the target */ mprPutStringToBuf(buf, mprJoinPath(appweb->platformDir, "bin")); } else if (matchToken(&cp, "${LIBS}")) { /* Required libraries to link. These may have nested ${TOKENS} */ mprPutStringToBuf(buf, espExpandCommand(eroute, getLibs(os), source, module)); } else if (matchToken(&cp, "${MOD}")) { /* Output module path in the cache without extension */ mprPutStringToBuf(buf, outputModule); } else if (matchToken(&cp, "${OBJ}")) { /* Output object with extension (.o) in the cache directory */ mprPutStringToBuf(buf, mprJoinPathExt(outputModule, getObjExt(os))); } else if (matchToken(&cp, "${OS}")) { /* Target architecture (freebsd|linux|macosx|windows|vxworks) */ mprPutStringToBuf(buf, os); } else if (matchToken(&cp, "${SHLIB}")) { /* .dll, .so, .dylib */ mprPutStringToBuf(buf, getShlibExt(os)); } else if (matchToken(&cp, "${SHOBJ}")) { /* .dll, .so, .dylib */ mprPutStringToBuf(buf, getShobjExt(os)); } else if (matchToken(&cp, "${SRC}")) { /* View (already parsed into C code) or controller source */ mprPutStringToBuf(buf, source); } else if (matchToken(&cp, "${TMP}")) { if ((tmp = getenv("TMPDIR")) == 0) { if ((tmp = getenv("TMP")) == 0) { tmp = getenv("TEMP"); } } mprPutStringToBuf(buf, tmp ? tmp : "."); } else if (matchToken(&cp, "${VS}")) { mprPutStringToBuf(buf, getVisualStudio()); } else if (matchToken(&cp, "${VXCPU}")) { mprPutStringToBuf(buf, getVxCPU(arch)); } else if (matchToken(&cp, "${WINSDK}")) { mprPutStringToBuf(buf, getWinSDK()); /* These vars can be configured from environment variables. NOTE: the default esp.conf includes "esp->vxworks.conf" which has EspEnv definitions for the configured VxWorks toolchain */ } else if (matchToken(&cp, "${CC}")) { mprPutStringToBuf(buf, getEnvString(eroute, "CC", getCompilerPath(os, arch))); } else if (matchToken(&cp, "${LINK}")) { mprPutStringToBuf(buf, getEnvString(eroute, "LINK", "")); } else if (matchToken(&cp, "${CFLAGS}")) { mprPutStringToBuf(buf, getEnvString(eroute, "CFLAGS", "")); } else if (matchToken(&cp, "${DEBUG}")) { mprPutStringToBuf(buf, getEnvString(eroute, "DEBUG", getDebug())); } else if (matchToken(&cp, "${LDFLAGS}")) { mprPutStringToBuf(buf, getEnvString(eroute, "LDFLAGS", "")); } else if (matchToken(&cp, "${WIND_BASE}")) { mprPutStringToBuf(buf, getEnvString(eroute, "WIND_BASE", WIND_BASE)); } else if (matchToken(&cp, "${WIND_HOME}")) { mprPutStringToBuf(buf, getEnvString(eroute, "WIND_HOME", WIND_HOME)); } else if (matchToken(&cp, "${WIND_HOST_TYPE}")) { mprPutStringToBuf(buf, getEnvString(eroute, "WIND_HOST_TYPE", WIND_HOST_TYPE)); } else if (matchToken(&cp, "${WIND_PLATFORM}")) { mprPutStringToBuf(buf, getEnvString(eroute, "WIND_PLATFORM", WIND_PLATFORM)); } else if (matchToken(&cp, "${WIND_GNU_PATH}")) { mprPutStringToBuf(buf, getEnvString(eroute, "WIND_GNU_PATH", WIND_GNU_PATH)); } else if (matchToken(&cp, "${WIND_CCNAME}")) { mprPutStringToBuf(buf, getEnvString(eroute, "WIND_CCNAME", getCompilerName(os, arch))); } else { mprPutCharToBuf(buf, *cp++); } } else { mprPutCharToBuf(buf, *cp++); } } mprAddNullToBuf(buf); return sclone(mprGetBufStart(buf)); }