summaryrefslogtreecommitdiff
path: root/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c')
-rwxr-xr-xsource4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c785
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
+ */