diff options
Diffstat (limited to 'source4/web_server/ejs/ejsProcs.c')
-rw-r--r-- | source4/web_server/ejs/ejsProcs.c | 705 |
1 files changed, 705 insertions, 0 deletions
diff --git a/source4/web_server/ejs/ejsProcs.c b/source4/web_server/ejs/ejsProcs.c new file mode 100644 index 0000000000..db9e5068c2 --- /dev/null +++ b/source4/web_server/ejs/ejsProcs.c @@ -0,0 +1,705 @@ +/* + * @file ejsProc.c + * @brief EJS support functions + */ +/********************************* Copyright **********************************/ +/* + * @copy default.g + * + * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved. + * Portions Copyright (c) GoAhead Software, 1995-2000. 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 "web_server/ejs/ejsInternal.h" + +#if BLD_FEATURE_EJS + +/****************************** Forward Declarations **************************/ +/* + * Object constructors + */ +static int objectConsProc(EjsHandle eid, int argc, MprVar **argv); +static int arrayConsProc(EjsHandle eid, int argc, MprVar **argv); +static int booleanConsProc(EjsHandle eid, int argc, MprVar **agv); +static int numberConsProc(EjsHandle eid, int argc, MprVar **argv); +static int stringConsProc(EjsHandle eid, int argc, MprVar **argv); + +/* + * Core functions + */ +static int toStringProc(EjsHandle eid, int argc, MprVar **argv); +static int valueOfProc(EjsHandle eid, int argc, MprVar **argv); + +/* + * Triggers + */ +static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op, + MprProperties *parentProperties, MprVar *prop, MprVar *newValue, + bool copyRef); + +/******************************************************************************/ +/* + * Routine to create the base common to all object types + */ + +MprVar ejsCreateObj(const char *name, int hashSize) +{ + MprVar o; + + o = mprCreateObjVar(name, hashSize); + if (o.type == MPR_TYPE_UNDEFINED) { + mprAssert(0); + return o; + } + + mprCreatePropertyValue(&o, "toString", + mprCreateCFunctionVar(toStringProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(&o, "valueOf", + mprCreateCFunctionVar(valueOfProc, 0, MPR_VAR_SCRIPT_HANDLE)); + return o; +} + +/******************************************************************************/ +/* + * Routine to destroy a variable + */ + +bool ejsDestroyVar(MprVar *obj) +{ + return mprDestroyVar(obj); +} + +/******************************************************************************/ +/* + * Routine to create the base array type + */ + +MprVar ejsCreateArray(const char *name, int size) +{ + MprVar obj, *lp, undef; + char idx[16]; + int i; + + /* Sanity limit for size of hash table */ + + obj = ejsCreateObj(name, max(size, 503)); + if (obj.type == MPR_TYPE_UNDEFINED) { + mprAssert(0); + return obj; + } + + undef = mprCreateUndefinedVar(); + for (i = 0; i < size; i++) { + mprItoa(i, idx, sizeof(idx)); + mprCreateProperty(&obj, idx, &undef); + } + + lp = mprCreatePropertyValue(&obj, "length", mprCreateIntegerVar(size)); + mprAssert(lp); + + mprSetVarReadonly(lp, 1); + mprAddVarTrigger(lp, lengthTrigger); + + return obj; +} + +/******************************************************************************/ +/******************************** Constructors ********************************/ +/******************************************************************************/ +/* + * Object constructor. Nothing really done here. For future expansion. + */ + +static int objectConsProc(EjsHandle eid, int argc, MprVar **argv) +{ +#if UNUSED + MprVar *obj; + Ejs *ep; + + if((ep = ejsPtr(eid)) == NULL) { + return -1; + } + + obj = mprGetProperty(ep->local, "this", 0); + mprAssert(obj); +#endif + return 0; +} + +/******************************************************************************/ +/* + * Array constructor + */ + +static int arrayConsProc(EjsHandle eid, int argc, MprVar **argv) +{ + MprVar *obj, *lp, undef; + Ejs *ep; + char idx[16]; + int i, max; + + objectConsProc(eid, argc, argv); + + if((ep = ejsPtr(eid)) == NULL) { + return -1; + } + obj = mprGetProperty(ep->local, "this", 0); + mprAssert(obj); + + + if (argc == 1) { + /* + * x = new Array(size); + */ + undef = mprCreateUndefinedVar(); + max = (int) mprVarToInteger(argv[0]); + for (i = 0; i < max; i++) { + mprItoa(i, idx, sizeof(idx)); + mprCreateProperty(obj, idx, &undef); + } + } else if (argc > 1) { + /* + * x = new Array(element0, element1, ..., elementN): + */ + max = argc; + for (i = 0; i < max; i++) { + mprItoa(i, idx, sizeof(idx)); + mprCreateProperty(obj, idx, argv[i]); + } + + } else { + max = 0; + } + + lp = mprCreatePropertyValue(obj, "length", mprCreateIntegerVar(max)); + mprAssert(lp); + + mprSetVarReadonly(lp, 1); + mprAddVarTrigger(lp, lengthTrigger); + + return 0; +} + +/******************************************************************************/ +/* + * Boolean constructor + */ + +static int booleanConsProc(EjsHandle eid, int argc, MprVar **argv) +{ + objectConsProc(eid, argc, argv); + return 0; +} + +/******************************************************************************/ +#if FUTURE +/* + * Date constructor + */ + +static int dateConsProc(EjsHandle eid, int argc, MprVar **argv) +{ + objectConsProc(eid, argc, argv); + return 0; +} + +#endif +/******************************************************************************/ +/* + * Number constructor + */ + +static int numberConsProc(EjsHandle eid, int argc, MprVar **argv) +{ + objectConsProc(eid, argc, argv); + return 0; +} + +/******************************************************************************/ +/* + * String constructor + */ + +static int stringConsProc(EjsHandle eid, int argc, MprVar **argv) +{ + objectConsProc(eid, argc, argv); + return 0; +} + +/******************************************************************************/ +/********************************** Functions *********************************/ +/******************************************************************************/ + +static int toStringProc(EjsHandle eid, int argc, MprVar **argv) +{ + MprVar *obj; + Ejs *ep; + char *buf; + int radix; + + if (argc == 0) { + radix = 10; + + } else if (argc == 1) { + radix = (int) mprVarToInteger(argv[0]); + + } else { + mprAssert(0); + return -1; + } + + if((ep = ejsPtr(eid)) == NULL) { + return -1; + } + + obj = mprGetProperty(ep->local, "this", 0); + mprAssert(obj); + + mprVarToString(&buf, MPR_MAX_STRING, 0, obj); + mprCopyVarValue(&ep->result, mprCreateStringVar(buf, 0), MPR_SHALLOW_COPY); + mprFree(buf); + + return 0; +} + +/******************************************************************************/ + +static int valueOfProc(EjsHandle eid, int argc, MprVar **argv) +{ + MprVar *obj; + Ejs *ep; + + if (argc != 0) { + mprAssert(0); + return -1; + } + + if((ep = ejsPtr(eid)) == NULL) { + return -1; + } + + obj = mprGetProperty(ep->local, "this", 0); + mprAssert(obj); + + switch (obj->type) { + default: + case MPR_TYPE_UNDEFINED: + case MPR_TYPE_NULL: + case MPR_TYPE_CFUNCTION: + case MPR_TYPE_OBJECT: + case MPR_TYPE_FUNCTION: + case MPR_TYPE_STRING_CFUNCTION: + mprCopyVar(&ep->result, obj, MPR_SHALLOW_COPY); + break; + + case MPR_TYPE_STRING: + mprCopyVarValue(&ep->result, mprCreateIntegerVar(atoi(obj->string)), 0); + break; + + case MPR_TYPE_BOOL: + case MPR_TYPE_INT: +#if BLD_FEATURE_INT64 + case MPR_TYPE_INT64: +#endif +#if BLD_FEATURE_FLOATING_POINT + case MPR_TYPE_FLOAT: +#endif + mprCopyVar(&ep->result, obj, 0); + break; + } + return 0; +} + +/******************************************************************************/ +/* + * Var access trigger on the Array.length property. Return the count of + * enumerable properties (don't count functions). + */ + +static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op, + MprProperties *parentProperties, MprVar *prop, MprVar *newValue, + bool copyRef) +{ + switch (op) { + case MPR_VAR_READ: + /* + * Subtract one for the length property + * FUTURE -- need an API to access parentProperties + * FUTURE -- contradiction to be read-only yet allow USE_NEW_VALUE. + * API needs finer control. + */ + *newValue = mprCreateIntegerVar(parentProperties->numDataItems - 1); + return MPR_TRIGGER_USE_NEW_VALUE; + + case MPR_VAR_WRITE: + return MPR_TRIGGER_ABORT; + + case MPR_VAR_CREATE_PROPERTY: + case MPR_VAR_DELETE_PROPERTY: + case MPR_VAR_DELETE: + default: + break; + } + return MPR_TRIGGER_PROCEED; +} + +/******************************************************************************/ +/**************************** Extension Functions *****************************/ +/******************************************************************************/ +/* + * Assert + */ + +static int assertProc(EjsHandle eid, int argc, MprVar **argv) +{ + bool b; + + if (argc < 1) { + ejsSetErrorMsg(eid, "usage: assert(condition)\n"); + return -1; + } + b = mprVarToBool(argv[0]); + if (b == 0) { + ejsSetErrorMsg(eid, "Assertion failure\n"); + return -1; + } + ejsSetReturnValue(eid, mprCreateBoolVar(b)); + return 0; +} + +/******************************************************************************/ +/* + * Exit + */ + +static int exitProc(EjsHandle eid, int argc, MprVar **argv) +{ + int status; + + if (argc < 1) { + ejsSetErrorMsg(eid, "usage: exit(status)\n"); + return -1; + } + status = (int) mprVarToInteger(argv[0]); + ejsSetExitStatus(eid, status); + + ejsSetReturnValue(eid, mprCreateStringVar("", 0)); + return 0; +} + +/******************************************************************************/ + +static void printVar(MprVar *vp, int recurseCount, int indent) +{ + MprVar *np; + char *buf; + int i; + + if (recurseCount > 5) { + write(1, "Skipping - recursion too deep\n", 29); + return; + } + + for (i = 0; i < indent; i++) { + write(1, " ", 2); + } + + if (vp->type == MPR_TYPE_OBJECT) { + if (vp->name) { + write(1, vp->name, strlen(vp->name)); + } else { + write(1, "unknown", 7); + } + write(1, ": {\n", 4); + np = mprGetFirstProperty(vp, MPR_ENUM_DATA); + while (np) { + if (strcmp(np->name, "local") == 0 || + strcmp(np->name, "global") == 0 || + strcmp(np->name, "this") == 0) { + np = mprGetNextProperty(vp, np, MPR_ENUM_DATA); + continue; + } + printVar(np, recurseCount + 1, indent + 1); + np = mprGetNextProperty(vp, np, MPR_ENUM_DATA); + if (np) { + write(1, ",\n", 2); + } + } + write(1, "\n", 1); + for (i = 0; i < indent; i++) { + write(1, " ", 2); + } + write(1, "}", 1); + + } else { + if (vp->name) { + write(1, vp->name, strlen(vp->name)); + } else { + write(1, "unknown", 7); + } + write(1, ": ", 2); + + /* FUTURE -- other types ? */ + mprVarToString(&buf, MPR_MAX_STRING, 0, vp); + if (vp->type == MPR_TYPE_STRING) { + write(1, "\"", 1); + } + write(1, buf, strlen(buf)); + if (vp->type == MPR_TYPE_STRING) { + write(1, "\"", 1); + } + mprFree(buf); + } +} + +/******************************************************************************/ +/* + * Print the args to stdout + */ + +static int printVarsProc(EjsHandle eid, int argc, MprVar **argv) +{ + MprVar *vp; + char *buf; + int i; + + for (i = 0; i < argc; i++) { + vp = argv[i]; + switch (vp->type) { + case MPR_TYPE_OBJECT: + printVar(vp, 0, 0); + break; + default: + mprVarToString(&buf, MPR_MAX_STRING, 0, vp); + write(1, buf, strlen(buf)); + mprFree(buf); + break; + } + } + write(1, "\n", 1); + + ejsSetReturnValue(eid, mprCreateStringVar("", 0)); + return 0; +} + +/******************************************************************************/ +/* + * Print the args to stdout + */ + +static int printProc(EjsHandle eid, int argc, MprVar **argv) +{ + char *buf; + int i; + + for (i = 0; i < argc; i++) { + mprVarToString(&buf, MPR_MAX_STRING, 0, argv[i]); + write(1, buf, strlen(buf)); + mprFree(buf); + } + return 0; +} + +/******************************************************************************/ +/* + * println + */ + +static int printlnProc(EjsHandle eid, int argc, MprVar **argv) +{ + printProc(eid, argc, argv); + write(1, "\n", 1); + return 0; +} + +/******************************************************************************/ +/* + * Trace + */ + +static int traceProc(EjsHandle eid, int argc, char **argv) +{ + if (argc == 1) { + mprLog(0, argv[0]); + + } else if (argc == 2) { + mprLog(atoi(argv[0]), argv[1]); + + } else { + ejsSetErrorMsg(eid, "Usage: trace([level], message)"); + return -1; + } + ejsSetReturnString(eid, ""); + return 0; +} + +/******************************************************************************/ +/* + * Return the object reference count + */ + +static int refCountProc(EjsHandle eid, int argc, MprVar **argv) +{ + MprVar *vp; + int count; + + vp = argv[0]; + if (vp->type == MPR_TYPE_OBJECT) { + count = mprGetVarRefCount(vp); + ejsSetReturnValue(eid, mprCreateIntegerVar(count)); + } else { + ejsSetReturnValue(eid, mprCreateIntegerVar(0)); + } + + return 0; +} + +/******************************************************************************/ +/* + * Evaluate a sub-script. It is evaluated in the same variable scope as + * the calling script / function. + */ + +static int evalScriptProc(EjsHandle eid, int argc, MprVar **argv) +{ + MprVar *arg; + char *emsg; + int i; + + ejsSetReturnValue(eid, mprCreateUndefinedVar()); + + for (i = 0; i < argc; i++) { + arg = argv[i]; + if (arg->type != MPR_TYPE_STRING) { + continue; + } + if (ejsEvalScript(eid, arg->string, 0, &emsg) < 0) { + ejsSetErrorMsg(eid, "%s", emsg); + mprFree(emsg); + return -1; + } + } + /* + * Return with the value of the last expression + */ + return 0; +} + +/******************************************************************************/ +/******************************************************************************/ +/******************************************************************************/ +/* + * Define the standard properties and functions inherited by all script engines. + */ + +int ejsDefineStandardProperties(MprVar *obj) +{ +#if BLD_FEATURE_FLOATING_POINT + double d = 0.0; + + /* FUTURE - this generates warnings on some systems. This is okay. */ + + mprCreatePropertyValue(obj, "NaN", mprCreateFloatVar(0.0 / d)); + d = MAX_FLOAT; + mprCreatePropertyValue(obj, "Infinity", mprCreateFloatVar(d * d)); +#endif + mprCreatePropertyValue(obj, "null", mprCreateNullVar()); + mprCreatePropertyValue(obj, "undefined", mprCreateUndefinedVar()); + mprCreatePropertyValue(obj, "true", mprCreateBoolVar(1)); + mprCreatePropertyValue(obj, "false", mprCreateBoolVar(0)); + +#if BLD_FEATURE_LEGACY_API + /* + * DEPRECATED: 2.0. + * So that ESP/ASP can ignore "language=javascript" statements + */ + mprCreatePropertyValue(obj, "javascript", mprCreateIntegerVar(0)); +#endif + + /* + * Extension functions + */ + mprCreatePropertyValue(obj, "assert", + mprCreateCFunctionVar(assertProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "eval", + mprCreateCFunctionVar(evalScriptProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "exit", + mprCreateCFunctionVar(exitProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "refCount", + mprCreateCFunctionVar(refCountProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "print", + mprCreateCFunctionVar(printProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "println", + mprCreateCFunctionVar(printlnProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "printVars", + mprCreateCFunctionVar(printVarsProc,0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "trace", + mprCreateStringCFunctionVar(traceProc, 0, MPR_VAR_SCRIPT_HANDLE)); + + /* + * Constructors + */ + mprCreatePropertyValue(obj, "Array", + mprCreateCFunctionVar(arrayConsProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "Boolean", + mprCreateCFunctionVar(booleanConsProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "Object", + mprCreateCFunctionVar(objectConsProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "Number", + mprCreateCFunctionVar(numberConsProc, 0, MPR_VAR_SCRIPT_HANDLE)); + mprCreatePropertyValue(obj, "String", + mprCreateCFunctionVar(stringConsProc, 0, MPR_VAR_SCRIPT_HANDLE)); + + /* mprCreatePropertyValue(obj, "Date", + * mprCreateCFunctionVar(dateConsProc, 0, MPR_VAR_SCRIPT_HANDLE)); + * mprCreatePropertyValue(obj, "Regexp", + * mprCreateCFunctionVar(regexpConsProc, 0, MPR_VAR_SCRIPT_HANDLE)); + */ + + /* + * Can we use on var x = "string text"; + */ + 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 + */ |