diff options
author | Derrell Lipman <derrell@samba.org> | 2006-09-26 16:58:27 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:20:21 -0500 |
commit | 77e8402dd68079c0e245fc8826daf2c6ad334766 (patch) | |
tree | 64f65c7d3fb7f3aa970311f70e3f8bae4c0fc40c /source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c | |
parent | 06de0f0b743056ba845de000339d4c3beb7cb845 (diff) | |
download | samba-77e8402dd68079c0e245fc8826daf2c6ad334766.tar.gz samba-77e8402dd68079c0e245fc8826daf2c6ad334766.tar.bz2 samba-77e8402dd68079c0e245fc8826daf2c6ad334766.zip |
r18925: Add current snapshot of the ejs-2.0 code. Tridge, will you be incorporating this?
(This used to be commit 917af234a8d517f82bd42256a940608a16b988f4)
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c')
-rwxr-xr-x | source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c | 785 |
1 files changed, 785 insertions, 0 deletions
diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c new file mode 100755 index 0000000000..6ab8f867e1 --- /dev/null +++ b/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c @@ -0,0 +1,785 @@ +/* + * @file ejsGlobal.c + * @brief EJS support methods + */ +/********************************* 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 + +/******************************************************************************/ +/************************************* Code ***********************************/ +/******************************************************************************/ +/* + * assert(condition) + */ + +static int assertProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + int b; + + if (argc < 1) { + ejsError(ep, EJS_ARG_ERROR, "usage: assert(condition)"); + return -1; + } + b = ejsVarToBoolean(argv[0]); + if (b == 0) { + ejsError(ep, EJS_ASSERT_ERROR, "Assertion failure at line %d", + ejsGetLineNumber(ep)); + return -1; + } + ejsWriteVarAsBoolean(ep, ep->result, b); + return 0; +} + +/******************************************************************************/ +/* + * breakpoint(msg) + */ + +static int breakpointProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + char *buf; + + if (argc < 1) { + return 0; + } + buf = ejsVarToString(ep, argv[0]); + if (buf) { + mprBreakpoint(0, buf); + } + return 0; +} + +/******************************************************************************/ +/* + * basename(path) + */ + +static int basenameProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + char *path; + + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "usage: basename(path)"); + return -1; + } + + path = ejsVarToString(ep, argv[0]); + if (path == 0) { + return MPR_ERR_MEMORY; + } + ejsSetReturnValueToString(ep, mprGetBaseName(path)); + + return 0; +} + +/******************************************************************************/ +/* + * stripext(path) + */ + +static int stripextProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + char *cp, *path, *stripPath; + + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "usage: stripext(path)"); + return -1; + } + + path = ejsVarToString(ep, argv[0]); + if (path == 0) { + return MPR_ERR_MEMORY; + } + stripPath = mprStrdup(ep, path); + + if ((cp = strrchr(stripPath, '.')) != 0) { + *cp = '\0'; + } + + ejsSetReturnValueToString(ep, stripPath); + + mprFree(stripPath); + + return 0; +} + +/******************************************************************************/ +/* + * dirname(path) + */ + +static int dirnameProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + char *path; + char dirname[MPR_MAX_FNAME]; + + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "usage: dirname(path)"); + return -1; + } + + path = ejsVarToString(ep, argv[0]); + if (path == 0) { + return MPR_ERR_MEMORY; + } + + ejsSetReturnValueToString(ep, + mprGetDirName(dirname, sizeof(dirname), path)); + + return 0; +} + +/******************************************************************************/ +/* + * trim(string) -- trim white space + */ + +static int trimProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + char *str, *buf, *cp; + + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "usage: trim(string)"); + return -1; + } + + str = ejsVarToString(ep, argv[0]); + if (str == 0) { + return MPR_ERR_MEMORY; + } + str = buf = mprStrdup(ep, str); + + while (isspace(*str)) { + str++; + } + cp = &str[strlen(str) - 1]; + while (cp >= str) { + if (isspace(*cp)) { + *cp = '\0'; + } else { + break; + } + cp--; + } + + ejsSetReturnValueToString(ep, str); + + mprFree(buf); + + return 0; +} + +/******************************************************************************/ +/* + * Terminate the script + */ + +static int exitScript(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + int status; + + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "usage: exit(status)"); + return -1; + } + status = (int) ejsVarToInteger(argv[0]); + ejsExit(ep, status); + + ejsWriteVarAsString(ep, ep->result, ""); + return 0; +} + +/******************************************************************************/ +/* + * include javascript libraries. + */ + +static int includeProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv) +{ + int i; + + mprAssert(argv); + + for (i = 0; i < argc; i++) { + if (ejsEvalFile(ep, argv[i], 0) < 0) { + return -1; + } + } + return 0; +} + +/******************************************************************************/ +/* + * include javascript libraries at the global level + */ + +static int includeGlobalProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv) +{ + int fid, i; + + mprAssert(argv); + + /* + * Create a new block and set the context to be the global scope + */ + fid = ejsSetBlock(ep, ep->global); + + for (i = 0; i < argc; i++) { + if (ejsEvalFile(ep, argv[i], 0) < 0) { + ejsCloseBlock(ep, fid); + return -1; + } + } + ejsCloseBlock(ep, fid); + return 0; +} + +/******************************************************************************/ +#if BLD_DEBUG +/* + * Print variables to stdout + */ + +static int printvProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + EjsVar *vp; + char *buf; + int i; + + for (i = 0; i < argc; ) { + vp = argv[i++]; + + /* mprPrintf(ep, "arg[%d] = ", i); */ + + buf = ejsVarToString(ep, vp); + + if (vp->propertyName == 0 || *vp->propertyName == '\0') { + mprPrintf(ep, "%s: ", buf); + + } else if (i < argc) { + mprPrintf(ep, "%s = %s, ", vp->propertyName, buf); + } else { + mprPrintf(ep, "%s = %s\n", vp->propertyName, buf); + } + } + return 0; +} + +#endif +/******************************************************************************/ +/* + * Print the args to stdout + */ + +static int printProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + char *buf; + int i; + + for (i = 0; i < argc; i++) { + buf = ejsVarToString(ep, argv[i]); + mprPrintf(ep, "%s", buf); + } + return 0; +} + +/******************************************************************************/ +/* + * println + */ + +static int printlnProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + printProc(ep, thisObj, argc, argv); + mprPrintf(ep, "\n"); + return 0; +} + +/******************************************************************************/ +#if FUTURE +/* + * sprintf + */ + +static int sprintfProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + va_list ap; + char *buf; + void **args; + int result; + + if (argc <= 1) { + ejsError(ep, EJS_ARG_ERROR, "Usage: sprintf(fmt, [args ...])"); + return -1; + } + + args = mprAlloc(ep, sizeof(void*) * (argc - 1)); + if (args == 0) { + mprAssert(args); + return -1; + } + + for (i = 1; i < argc; i++) { + args[i - 1] = argv[i]); + } + + va_start(ap, fmt); + *buf = 0; + result = inner(0, &buf, MPR_MAX_STRING, fmt, args); + va_end(ap); + + ejsSetReturnValueToString(ep, buf); + + mprFree(buf); + return 0; +} + +/******************************************************************************/ + +inner(const char *fmt, void **args) +{ + va_list ap; + + va_start(ap, fmt); + *buf = 0; + mprSprintfCore(ctx, &buf, maxSize, fmt, ap, MPR_PRINTF_ARGV); + va_end(ap); +} + +#endif +/******************************************************************************/ +/* + * sleep + */ + +static int sleepProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "Usage: sleep(milliseconds)"); + return -1; + } + mprSleep(ep, ejsVarToInteger(argv[0])); + return 0; +} + +/******************************************************************************/ +/* + * sort properties + * FUTURE -- should have option to sort object based on a given property value + * ascending or descending + * Usage: sort(object, order = ascending, property = 0); + */ + +static int sortProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + const char *property; + int error, order; + + error = 0; + property = 0; + + /* + * Default order is increasing + */ + order = 1; + + if (argc < 1 || argc > 3 || !ejsVarIsObject(argv[0])) { + error++; + } + + if (argc >= 2) { + order = ejsVarToInteger(argv[1]); + } + + /* + * If property is not defined, it sorts the properties in the object + */ + if (argc == 3) { + if (! ejsVarIsString(argv[2])) { + error++; + } else { + property = argv[2]->string; + } + } + + if (error) { + ejsError(ep, EJS_ARG_ERROR, "Usage: sort(object, [order], [property])"); + return -1; + } + ejsSortProperties(ep, argv[0], 0, property, order); + return 0; +} + +/******************************************************************************/ +/* + * Get a time mark + * MOB -- WARNING: this can overflow. OK on BREW, but other O/Ss it may have + * overflowed on the first call. It should be renamed. + * MOB -- replace with proper Date. + */ + +static int timeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + MprTime now; + + mprGetTime(ep, &now); +#if WIN || LINUX || SOLARIS +{ + /* MOB -- poor hack */ + static MprTime initial; + if (initial.sec == 0) { + initial = now; + } + now.sec -= initial.sec; + + if (initial.msec > now.msec) { + now.msec = now.msec + 1000 - initial.msec; + now.sec--; + } else { + now.msec -= initial.msec; + } +} +#endif + /* MOB -- this can overflow */ + ejsSetReturnValueToInteger(ep, now.sec * 1000 + now.msec); + return 0; +} + +/******************************************************************************/ +/* + * MOB -- Temporary Get the date (time since Jan 6, 1980 GMT + */ + +static int dateProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ +#if BREW + uint now; + + now = GETTIMESECONDS(); + ejsSetReturnValueToInteger(ep, now); +#endif + return 0; +} + +/******************************************************************************/ +/* + * strlen(string) + */ + +static int strlenProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + char *buf; + int len; + + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "Usage: strlen(var)"); + return -1; + } + + len = 0; + if (! ejsVarIsString(argv[0])) { + buf = ejsVarToString(ep, argv[0]); + if (buf) { + len = strlen(buf); + } + + } else { + len = argv[0]->length; + } + + ejsSetReturnValueToInteger(ep, len); + return 0; +} + +/******************************************************************************/ +/* + * toint(num) + */ + +static int tointProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + int i; + + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "Usage: toint(number)"); + return -1; + } + + i = ejsVarToInteger(argv[0]); + + ejsSetReturnValueToInteger(ep, i); + return 0; +} + +/******************************************************************************/ +/* + * string strstr(string, pat) + */ + +static int strstrProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + char *str, *pat; + char *s; + int strAlloc; + + if (argc != 2) { + ejsError(ep, EJS_ARG_ERROR, "Usage: strstr(string, pat)"); + return -1; + } + + str = ejsVarToString(ep, argv[0]); + + strAlloc = ep->castAlloc; + ep->castTemp = 0; + + pat = ejsVarToString(ep, argv[1]); + + s = strstr(str, pat); + + if (s == 0) { + ejsSetReturnValueToUndefined(ep); + } else { + ejsSetReturnValueToString(ep, s); + } + + if (strAlloc) { + mprFree(str); + } + + return 0; +} + +/******************************************************************************/ +/* + * Trace + */ + +static int traceProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv) +{ + if (argc == 1) { + mprLog(ep, 0, "%s", argv[0]); + + } else if (argc == 2) { + mprLog(ep, atoi(argv[0]), "%s", argv[1]); + + } else { + ejsError(ep, EJS_ARG_ERROR, "Usage: trace([level], message)"); + return -1; + } + ejsWriteVarAsString(ep, ep->result, ""); + return 0; +} + +/******************************************************************************/ +/* + * Evaluate a sub-script. It is evaluated in the same variable scope as + * the calling script / method. + */ + +static int evalScriptProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + EjsVar *arg; + int i; + + ejsWriteVarAsUndefined(ep, ep->result); + + for (i = 0; i < argc; i++) { + arg = argv[i]; + if (arg->type != EJS_TYPE_STRING) { + continue; + } + if (ejsEvalScript(ep, arg->string, 0) < 0) { + return -1; + } + } + /* + * Return with the value of the last expression + */ + return 0; +} + +/******************************************************************************/ + +/* MOB -- need a real datatype returning int, int64, etc */ + +static int typeofProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) +{ + const struct { + EjsType type; + const char *name; + } types[] = { + { EJS_TYPE_UNDEFINED, "undefined" }, +#if EJS_ECMA_STND + { EJS_TYPE_NULL, "object" }, +#else + { EJS_TYPE_NULL, "null" }, +#endif + { EJS_TYPE_BOOL, "boolean" }, + { EJS_TYPE_CMETHOD, "function" }, + { EJS_TYPE_FLOAT, "number" }, + { EJS_TYPE_INT, "number" }, + { EJS_TYPE_INT64, "number" }, + { EJS_TYPE_OBJECT, "object" }, + { EJS_TYPE_METHOD, "function" }, + { EJS_TYPE_STRING, "string" }, + { EJS_TYPE_STRING_CMETHOD, "function" }, + { EJS_TYPE_PTR, "pointer" } + }; + const char *type; + int i; + + type = NULL; + if (argc != 1) { + ejsError(ep, EJS_ARG_ERROR, "Bad args: typeof(var)"); + return -1; + } + + for (i = 0; i < MPR_ARRAY_SIZE(types); i++) { + if (argv[0]->type == types[i].type) { + type = types[i].name; + break; + } + } + if (type == NULL) { + mprAssert(type); + return -1; + } + + ejsSetReturnValueToString(ep, type); + return 0; +} + +/******************************************************************************/ +/* + * Define the standard properties and methods inherited by all interpreters + * Obj is set to the global class in the default interpreter. When an + * interpreter attempts to write to any property, a copy will be written + * into the interpeters own global space. This is like a "copy-on-write". + */ + +int ejsDefineGlobalProperties(Ejs *ep) +{ + EjsVar *obj; + + obj = ep->service->globalClass; + mprAssert(obj); + + ejsSetPropertyToNull(ep, obj, "null"); + ejsSetPropertyToUndefined(ep, obj, "undefined"); + ejsSetPropertyToBoolean(ep, obj, "true", 1); + ejsSetPropertyToBoolean(ep, obj, "false", 0); + +#if BLD_FEATURE_FLOATING_POINT + { + /* MOB. Fix. This generates warnings on some systems. + This is intended. */ + double d = 0.0; + double e = 0.0; + ejsSetPropertyToFloat(ep, obj, "NaN", e / d); + + d = MAX_FLOAT; + ejsSetPropertyToFloat(ep, obj, "Infinity", d * d); + } +#endif + +#if BLD_FEATURE_LEGACY_API + /* + * DEPRECATED: 2.0. + * So that ESP/ASP can ignore "language=javascript" statements + */ + ejsSetPropertyToInteger(ep, obj, "javascript", 0); +#endif + + /* + * Extension methods. We go directly to the mpr property APIs for speed. + * Flags will cause the callbacks to be supplied the Ejs handle. + */ + ejsDefineCMethod(ep, obj, "assert", assertProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "breakpoint", breakpointProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "basename", basenameProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "dirname", dirnameProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "stripext", stripextProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "trim", trimProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "eval", evalScriptProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "exit", exitScript, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "print", printProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "println", printlnProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "sleep", sleepProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "sort", sortProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "time", timeProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "date", dateProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "strlen", strlenProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "strstr", strstrProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "typeof", typeofProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "toint", tointProc, EJS_NO_LOCAL); + + ejsDefineStringCMethod(ep, obj, "include", includeProc, EJS_NO_LOCAL); + ejsDefineStringCMethod(ep, obj, "includeGlobal", includeGlobalProc, + EJS_NO_LOCAL); + ejsDefineStringCMethod(ep, obj, "trace", traceProc, EJS_NO_LOCAL); + +#if BLD_DEBUG + ejsDefineCMethod(ep, obj, "printv", printvProc, EJS_NO_LOCAL); +#endif + +#if FUTURE + ejsDefineCMethod(ep, obj, "printf", printfProc, EJS_NO_LOCAL); + ejsDefineCMethod(ep, obj, "sprintf", sprintfProc, EJS_NO_LOCAL); +#endif + + if (ejsObjHasErrors(obj)) { + return MPR_ERR_CANT_INITIALIZE; + } + return 0; +} + +/******************************************************************************/ + +#else +void ejsProcsDummy() {} + +/******************************************************************************/ +#endif /* BLD_FEATURE_EJS */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim:tw=78 + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ |