3 * @brief EJS support functions
5 /********************************* Copyright **********************************/
9 * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
10 * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
12 * This software is distributed under commercial and open source licenses.
13 * You may use the GPL open source license described below or you may acquire
14 * a commercial license from Mbedthis Software. You agree to be fully bound
15 * by the terms of either license. Consult the LICENSE.TXT distributed with
16 * this software for full details.
18 * This software is open source; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2 of the License, or (at your
21 * option) any later version. See the GNU General Public License for more
22 * details at: http://www.mbedthis.com/downloads/gplLicense.html
24 * This program is distributed WITHOUT ANY WARRANTY; without even the
25 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27 * This GPL license does NOT permit incorporating this software into
28 * proprietary programs. If you are unable to comply with the GPL, you must
29 * acquire a commercial license to use this software. Commercial licenses
30 * for this software and support services are available from Mbedthis
31 * Software at http://www.mbedthis.com
35 /********************************** Includes **********************************/
37 #include "web_server/ejs/ejsInternal.h"
41 /****************************** Forward Declarations **************************/
45 static int objectConsProc(EjsHandle eid, int argc, MprVar **argv);
46 static int arrayConsProc(EjsHandle eid, int argc, MprVar **argv);
47 static int booleanConsProc(EjsHandle eid, int argc, MprVar **agv);
48 static int numberConsProc(EjsHandle eid, int argc, MprVar **argv);
49 static int stringConsProc(EjsHandle eid, int argc, MprVar **argv);
54 static int toStringProc(EjsHandle eid, int argc, MprVar **argv);
55 static int valueOfProc(EjsHandle eid, int argc, MprVar **argv);
60 static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op,
61 MprProperties *parentProperties, MprVar *prop, MprVar *newValue,
64 /******************************************************************************/
66 * Routine to create the base common to all object types
69 MprVar ejsCreateObj(const char *name, int hashSize)
73 o = mprCreateObjVar(name, hashSize);
74 if (o.type == MPR_TYPE_UNDEFINED) {
79 mprCreatePropertyValue(&o, "toString",
80 mprCreateCFunctionVar(toStringProc, 0, MPR_VAR_SCRIPT_HANDLE));
81 mprCreatePropertyValue(&o, "valueOf",
82 mprCreateCFunctionVar(valueOfProc, 0, MPR_VAR_SCRIPT_HANDLE));
86 /******************************************************************************/
88 * Routine to destroy a variable
91 bool ejsDestroyVar(MprVar *obj)
93 return mprDestroyVar(obj);
96 /******************************************************************************/
98 * Routine to create the base array type
101 MprVar ejsCreateArray(const char *name, int size)
103 MprVar obj, *lp, undef;
107 /* Sanity limit for size of hash table */
109 obj = ejsCreateObj(name, max(size, 503));
110 if (obj.type == MPR_TYPE_UNDEFINED) {
115 undef = mprCreateUndefinedVar();
116 for (i = 0; i < size; i++) {
117 mprItoa(i, idx, sizeof(idx));
118 mprCreateProperty(&obj, idx, &undef);
121 lp = mprCreatePropertyValue(&obj, "length", mprCreateIntegerVar(size));
124 mprSetVarReadonly(lp, 1);
125 mprAddVarTrigger(lp, lengthTrigger);
130 /******************************************************************************/
131 /******************************** Constructors ********************************/
132 /******************************************************************************/
134 * Object constructor. Nothing really done here. For future expansion.
137 static int objectConsProc(EjsHandle eid, int argc, MprVar **argv)
143 if((ep = ejsPtr(eid)) == NULL) {
147 obj = mprGetProperty(ep->local, "this", 0);
153 /******************************************************************************/
158 static int arrayConsProc(EjsHandle eid, int argc, MprVar **argv)
160 MprVar *obj, *lp, undef;
165 objectConsProc(eid, argc, argv);
167 if((ep = ejsPtr(eid)) == NULL) {
170 obj = mprGetProperty(ep->local, "this", 0);
176 * x = new Array(size);
178 undef = mprCreateUndefinedVar();
179 max = (int) mprVarToInteger(argv[0]);
180 for (i = 0; i < max; i++) {
181 mprItoa(i, idx, sizeof(idx));
182 mprCreateProperty(obj, idx, &undef);
184 } else if (argc > 1) {
186 * x = new Array(element0, element1, ..., elementN):
189 for (i = 0; i < max; i++) {
190 mprItoa(i, idx, sizeof(idx));
191 mprCreateProperty(obj, idx, argv[i]);
198 lp = mprCreatePropertyValue(obj, "length", mprCreateIntegerVar(max));
201 mprSetVarReadonly(lp, 1);
202 mprAddVarTrigger(lp, lengthTrigger);
207 /******************************************************************************/
209 * Boolean constructor
212 static int booleanConsProc(EjsHandle eid, int argc, MprVar **argv)
214 objectConsProc(eid, argc, argv);
218 /******************************************************************************/
224 static int dateConsProc(EjsHandle eid, int argc, MprVar **argv)
226 objectConsProc(eid, argc, argv);
231 /******************************************************************************/
236 static int numberConsProc(EjsHandle eid, int argc, MprVar **argv)
238 objectConsProc(eid, argc, argv);
242 /******************************************************************************/
247 static int stringConsProc(EjsHandle eid, int argc, MprVar **argv)
249 objectConsProc(eid, argc, argv);
253 /******************************************************************************/
254 /********************************** Functions *********************************/
255 /******************************************************************************/
257 static int toStringProc(EjsHandle eid, int argc, MprVar **argv)
267 } else if (argc == 1) {
268 radix = (int) mprVarToInteger(argv[0]);
275 if((ep = ejsPtr(eid)) == NULL) {
279 obj = mprGetProperty(ep->local, "this", 0);
282 mprVarToString(&buf, MPR_MAX_STRING, 0, obj);
283 mprCopyVarValue(&ep->result, mprCreateStringVar(buf, 0), MPR_SHALLOW_COPY);
289 /******************************************************************************/
291 static int valueOfProc(EjsHandle eid, int argc, MprVar **argv)
301 if((ep = ejsPtr(eid)) == NULL) {
305 obj = mprGetProperty(ep->local, "this", 0);
310 case MPR_TYPE_UNDEFINED:
312 case MPR_TYPE_CFUNCTION:
313 case MPR_TYPE_OBJECT:
314 case MPR_TYPE_FUNCTION:
315 case MPR_TYPE_STRING_CFUNCTION:
316 mprCopyVar(&ep->result, obj, MPR_SHALLOW_COPY);
319 case MPR_TYPE_STRING:
320 mprCopyVarValue(&ep->result, mprCreateIntegerVar(atoi(obj->string)), 0);
325 #if BLD_FEATURE_INT64
328 #if BLD_FEATURE_FLOATING_POINT
331 mprCopyVar(&ep->result, obj, 0);
337 /******************************************************************************/
339 * Var access trigger on the Array.length property. Return the count of
340 * enumerable properties (don't count functions).
343 static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op,
344 MprProperties *parentProperties, MprVar *prop, MprVar *newValue,
350 * Subtract one for the length property
351 * FUTURE -- need an API to access parentProperties
352 * FUTURE -- contradiction to be read-only yet allow USE_NEW_VALUE.
353 * API needs finer control.
355 *newValue = mprCreateIntegerVar(parentProperties->numDataItems - 1);
356 return MPR_TRIGGER_USE_NEW_VALUE;
359 return MPR_TRIGGER_ABORT;
361 case MPR_VAR_CREATE_PROPERTY:
362 case MPR_VAR_DELETE_PROPERTY:
367 return MPR_TRIGGER_PROCEED;
370 /******************************************************************************/
371 /**************************** Extension Functions *****************************/
372 /******************************************************************************/
377 static int assertProc(EjsHandle eid, int argc, MprVar **argv)
382 ejsSetErrorMsg(eid, "usage: assert(condition)\n");
385 b = mprVarToBool(argv[0]);
387 ejsSetErrorMsg(eid, "Assertion failure\n");
390 ejsSetReturnValue(eid, mprCreateBoolVar(b));
394 /******************************************************************************/
399 static int exitProc(EjsHandle eid, int argc, MprVar **argv)
404 ejsSetErrorMsg(eid, "usage: exit(status)\n");
407 status = (int) mprVarToInteger(argv[0]);
408 ejsSetExitStatus(eid, status);
410 ejsSetReturnValue(eid, mprCreateStringVar("", 0));
414 /******************************************************************************/
416 static void printVar(MprVar *vp, int recurseCount, int indent)
422 if (recurseCount > 5) {
423 write(1, "Skipping - recursion too deep\n", 29);
427 for (i = 0; i < indent; i++) {
431 if (vp->type == MPR_TYPE_OBJECT) {
433 write(1, vp->name, strlen(vp->name));
435 write(1, "unknown", 7);
437 write(1, ": {\n", 4);
438 np = mprGetFirstProperty(vp, MPR_ENUM_DATA);
440 if (strcmp(np->name, "local") == 0 ||
441 strcmp(np->name, "global") == 0 ||
442 strcmp(np->name, "this") == 0) {
443 np = mprGetNextProperty(vp, np, MPR_ENUM_DATA);
446 printVar(np, recurseCount + 1, indent + 1);
447 np = mprGetNextProperty(vp, np, MPR_ENUM_DATA);
453 for (i = 0; i < indent; i++) {
460 write(1, vp->name, strlen(vp->name));
462 write(1, "unknown", 7);
466 /* FUTURE -- other types ? */
467 mprVarToString(&buf, MPR_MAX_STRING, 0, vp);
468 if (vp->type == MPR_TYPE_STRING) {
471 write(1, buf, strlen(buf));
472 if (vp->type == MPR_TYPE_STRING) {
479 /******************************************************************************/
481 * Print the args to stdout
484 static int printVarsProc(EjsHandle eid, int argc, MprVar **argv)
490 for (i = 0; i < argc; i++) {
493 case MPR_TYPE_OBJECT:
497 mprVarToString(&buf, MPR_MAX_STRING, 0, vp);
498 write(1, buf, strlen(buf));
505 ejsSetReturnValue(eid, mprCreateStringVar("", 0));
509 /******************************************************************************/
511 * Print the args to stdout
514 static int printProc(EjsHandle eid, int argc, MprVar **argv)
519 for (i = 0; i < argc; i++) {
520 mprVarToString(&buf, MPR_MAX_STRING, 0, argv[i]);
521 write(1, buf, strlen(buf));
527 /******************************************************************************/
532 static int printlnProc(EjsHandle eid, int argc, MprVar **argv)
534 printProc(eid, argc, argv);
539 /******************************************************************************/
544 static int traceProc(EjsHandle eid, int argc, char **argv)
547 mprLog(0, "%s", argv[0]);
549 } else if (argc == 2) {
550 mprLog(atoi(argv[0]), "%s", argv[1]);
553 ejsSetErrorMsg(eid, "Usage: trace([level], message)");
556 ejsSetReturnString(eid, "");
560 /******************************************************************************/
562 * Return the object reference count
565 static int refCountProc(EjsHandle eid, int argc, MprVar **argv)
571 if (vp->type == MPR_TYPE_OBJECT) {
572 count = mprGetVarRefCount(vp);
573 ejsSetReturnValue(eid, mprCreateIntegerVar(count));
575 ejsSetReturnValue(eid, mprCreateIntegerVar(0));
581 /******************************************************************************/
583 * Evaluate a sub-script. It is evaluated in the same variable scope as
584 * the calling script / function.
587 static int evalScriptProc(EjsHandle eid, int argc, MprVar **argv)
593 ejsSetReturnValue(eid, mprCreateUndefinedVar());
595 for (i = 0; i < argc; i++) {
597 if (arg->type != MPR_TYPE_STRING) {
600 if (ejsEvalScript(eid, arg->string, 0, &emsg) < 0) {
601 ejsSetErrorMsg(eid, "%s", emsg);
607 * Return with the value of the last expression
612 /******************************************************************************/
613 /******************************************************************************/
614 /******************************************************************************/
616 * Define the standard properties and functions inherited by all script engines.
619 int ejsDefineStandardProperties(MprVar *obj)
621 #if BLD_FEATURE_FLOATING_POINT
624 /* FUTURE - this generates warnings on some systems. This is okay. */
626 mprCreatePropertyValue(obj, "NaN", mprCreateFloatVar(0.0 / d));
628 mprCreatePropertyValue(obj, "Infinity", mprCreateFloatVar(d * d));
630 mprCreatePropertyValue(obj, "null", mprCreateNullVar());
631 mprCreatePropertyValue(obj, "undefined", mprCreateUndefinedVar());
632 mprCreatePropertyValue(obj, "true", mprCreateBoolVar(1));
633 mprCreatePropertyValue(obj, "false", mprCreateBoolVar(0));
635 #if BLD_FEATURE_LEGACY_API
638 * So that ESP/ASP can ignore "language=javascript" statements
640 mprCreatePropertyValue(obj, "javascript", mprCreateIntegerVar(0));
644 * Extension functions
646 mprCreatePropertyValue(obj, "assert",
647 mprCreateCFunctionVar(assertProc, 0, MPR_VAR_SCRIPT_HANDLE));
648 mprCreatePropertyValue(obj, "eval",
649 mprCreateCFunctionVar(evalScriptProc, 0, MPR_VAR_SCRIPT_HANDLE));
650 mprCreatePropertyValue(obj, "exit",
651 mprCreateCFunctionVar(exitProc, 0, MPR_VAR_SCRIPT_HANDLE));
652 mprCreatePropertyValue(obj, "refCount",
653 mprCreateCFunctionVar(refCountProc, 0, MPR_VAR_SCRIPT_HANDLE));
654 mprCreatePropertyValue(obj, "print",
655 mprCreateCFunctionVar(printProc, 0, MPR_VAR_SCRIPT_HANDLE));
656 mprCreatePropertyValue(obj, "println",
657 mprCreateCFunctionVar(printlnProc, 0, MPR_VAR_SCRIPT_HANDLE));
658 mprCreatePropertyValue(obj, "printVars",
659 mprCreateCFunctionVar(printVarsProc,0, MPR_VAR_SCRIPT_HANDLE));
660 mprCreatePropertyValue(obj, "trace",
661 mprCreateStringCFunctionVar(traceProc, 0, MPR_VAR_SCRIPT_HANDLE));
666 mprCreatePropertyValue(obj, "Array",
667 mprCreateCFunctionVar(arrayConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
668 mprCreatePropertyValue(obj, "Boolean",
669 mprCreateCFunctionVar(booleanConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
670 mprCreatePropertyValue(obj, "Object",
671 mprCreateCFunctionVar(objectConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
672 mprCreatePropertyValue(obj, "Number",
673 mprCreateCFunctionVar(numberConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
674 mprCreatePropertyValue(obj, "String",
675 mprCreateCFunctionVar(stringConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
677 /* mprCreatePropertyValue(obj, "Date",
678 * mprCreateCFunctionVar(dateConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
679 * mprCreatePropertyValue(obj, "Regexp",
680 * mprCreateCFunctionVar(regexpConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
684 * Can we use on var x = "string text";
689 /******************************************************************************/
692 void ejsProcsDummy() {}
694 /******************************************************************************/
695 #endif /* BLD_FEATURE_EJS */
703 * vim600: sw=4 ts=4 fdm=marker