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 "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);
174 if (argc == 1 && mprVarIsNumber(argv[0]->type)) {
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);
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]);
195 lp = mprCreatePropertyValue(obj, "length", mprCreateIntegerVar(max));
198 mprSetVarReadonly(lp, 1);
199 mprAddVarTrigger(lp, lengthTrigger);
204 /******************************************************************************/
206 * Boolean constructor
209 static int booleanConsProc(EjsHandle eid, int argc, MprVar **argv)
211 objectConsProc(eid, argc, argv);
215 /******************************************************************************/
221 static int dateConsProc(EjsHandle eid, int argc, MprVar **argv)
223 objectConsProc(eid, argc, argv);
228 /******************************************************************************/
233 static int numberConsProc(EjsHandle eid, int argc, MprVar **argv)
235 objectConsProc(eid, argc, argv);
239 /******************************************************************************/
244 static int stringConsProc(EjsHandle eid, int argc, MprVar **argv)
246 objectConsProc(eid, argc, argv);
250 /******************************************************************************/
251 /********************************** Functions *********************************/
252 /******************************************************************************/
254 static int toStringProc(EjsHandle eid, int argc, MprVar **argv)
264 } else if (argc == 1) {
265 radix = (int) mprVarToInteger(argv[0]);
272 if((ep = ejsPtr(eid)) == NULL) {
276 obj = mprGetProperty(ep->local, "this", 0);
279 mprVarToString(&buf, MPR_MAX_STRING, 0, obj);
280 mprCopyVarValue(&ep->result, mprCreateStringVar(buf, 0), MPR_SHALLOW_COPY);
286 /******************************************************************************/
288 static int valueOfProc(EjsHandle eid, int argc, MprVar **argv)
298 if((ep = ejsPtr(eid)) == NULL) {
302 obj = mprGetProperty(ep->local, "this", 0);
307 case MPR_TYPE_UNDEFINED:
309 case MPR_TYPE_CFUNCTION:
310 case MPR_TYPE_OBJECT:
311 case MPR_TYPE_FUNCTION:
312 case MPR_TYPE_STRING_CFUNCTION:
314 mprCopyVar(&ep->result, obj, MPR_SHALLOW_COPY);
317 case MPR_TYPE_STRING:
318 mprCopyVarValue(&ep->result, mprCreateIntegerVar(atoi(obj->string)), 0);
323 #if BLD_FEATURE_INT64
326 #if BLD_FEATURE_FLOATING_POINT
329 mprCopyVar(&ep->result, obj, 0);
335 /******************************************************************************/
337 * Var access trigger on the Array.length property. Return the count of
338 * enumerable properties (don't count functions).
341 static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op,
342 MprProperties *parentProperties, MprVar *prop, MprVar *newValue,
348 * Subtract one for the length property
349 * FUTURE -- need an API to access parentProperties
350 * FUTURE -- contradiction to be read-only yet allow USE_NEW_VALUE.
351 * API needs finer control.
353 *newValue = mprCreateIntegerVar(parentProperties->numDataItems - 1);
354 return MPR_TRIGGER_USE_NEW_VALUE;
357 return MPR_TRIGGER_ABORT;
359 case MPR_VAR_CREATE_PROPERTY:
360 case MPR_VAR_DELETE_PROPERTY:
365 return MPR_TRIGGER_PROCEED;
368 /******************************************************************************/
369 /**************************** Extension Functions *****************************/
370 /******************************************************************************/
375 static int assertProc(EjsHandle eid, int argc, MprVar **argv)
380 ejsSetErrorMsg(eid, "usage: assert(condition)\n");
383 b = mprVarToBool(argv[0]);
385 ejsSetErrorMsg(eid, "Assertion failure\n");
388 ejsSetReturnValue(eid, mprCreateBoolVar(b));
392 /******************************************************************************/
397 static int exitProc(EjsHandle eid, int argc, MprVar **argv)
402 ejsSetErrorMsg(eid, "usage: exit(status)\n");
405 status = (int) mprVarToInteger(argv[0]);
406 ejsSetExitStatus(eid, status);
408 ejsSetReturnValue(eid, mprCreateStringVar("", 0));
412 /******************************************************************************/
414 static void printVar(MprVar *vp, int recurseCount, int indent)
420 if (recurseCount > 5) {
421 write(1, "Skipping - recursion too deep\n", 29);
425 for (i = 0; i < indent; i++) {
429 if (vp->type == MPR_TYPE_OBJECT) {
431 write(1, vp->name, strlen(vp->name));
433 write(1, "unknown", 7);
435 write(1, ": {\n", 4);
436 np = mprGetFirstProperty(vp, MPR_ENUM_DATA);
438 if (strcmp(np->name, "local") == 0 ||
439 strcmp(np->name, "global") == 0 ||
440 strcmp(np->name, "this") == 0) {
441 np = mprGetNextProperty(vp, np, MPR_ENUM_DATA);
444 printVar(np, recurseCount + 1, indent + 1);
445 np = mprGetNextProperty(vp, np, MPR_ENUM_DATA);
451 for (i = 0; i < indent; i++) {
458 write(1, vp->name, strlen(vp->name));
460 write(1, "unknown", 7);
464 /* FUTURE -- other types ? */
465 mprVarToString(&buf, MPR_MAX_STRING, 0, vp);
466 if (vp->type == MPR_TYPE_STRING) {
469 write(1, buf, strlen(buf));
470 if (vp->type == MPR_TYPE_STRING) {
477 /******************************************************************************/
479 * Print the args to stdout
482 static int printVarsProc(EjsHandle eid, int argc, MprVar **argv)
488 for (i = 0; i < argc; i++) {
491 case MPR_TYPE_OBJECT:
495 mprVarToString(&buf, MPR_MAX_STRING, 0, vp);
496 write(1, buf, strlen(buf));
503 ejsSetReturnValue(eid, mprCreateStringVar("", 0));
507 /******************************************************************************/
509 * Print the args to stdout
512 static int printProc(EjsHandle eid, int argc, MprVar **argv)
517 for (i = 0; i < argc; i++) {
518 mprVarToString(&buf, MPR_MAX_STRING, 0, argv[i]);
519 write(1, buf, strlen(buf));
525 /******************************************************************************/
530 static int printlnProc(EjsHandle eid, int argc, MprVar **argv)
532 printProc(eid, argc, argv);
537 /******************************************************************************/
542 static int traceProc(EjsHandle eid, int argc, char **argv)
545 mprLog(0, "%s", argv[0]);
547 } else if (argc == 2) {
548 mprLog(atoi(argv[0]), "%s", argv[1]);
551 ejsSetErrorMsg(eid, "Usage: trace([level], message)");
554 ejsSetReturnString(eid, "");
558 /******************************************************************************/
560 * Return the object reference count
563 static int refCountProc(EjsHandle eid, int argc, MprVar **argv)
569 if (vp->type == MPR_TYPE_OBJECT) {
570 count = mprGetVarRefCount(vp);
571 ejsSetReturnValue(eid, mprCreateIntegerVar(count));
573 ejsSetReturnValue(eid, mprCreateIntegerVar(0));
579 /******************************************************************************/
581 * Evaluate a sub-script. It is evaluated in the same variable scope as
582 * the calling script / function.
585 static int evalScriptProc(EjsHandle eid, int argc, MprVar **argv)
591 ejsSetReturnValue(eid, mprCreateUndefinedVar());
593 for (i = 0; i < argc; i++) {
595 if (arg->type != MPR_TYPE_STRING) {
598 if (ejsEvalScript(eid, arg->string, 0, &emsg) < 0) {
599 ejsSetErrorMsg(eid, "%s", emsg);
605 * Return with the value of the last expression
610 /******************************************************************************/
611 /******************************************************************************/
612 /******************************************************************************/
614 * Define the standard properties and functions inherited by all script engines.
617 int ejsDefineStandardProperties(MprVar *obj)
619 #if BLD_FEATURE_FLOATING_POINT
622 /* FUTURE - this generates warnings on some systems. This is okay. */
624 mprCreatePropertyValue(obj, "NaN", mprCreateFloatVar(0.0 / d));
626 mprCreatePropertyValue(obj, "Infinity", mprCreateFloatVar(d * d));
628 mprCreatePropertyValue(obj, "null", mprCreateNullVar());
629 mprCreatePropertyValue(obj, "undefined", mprCreateUndefinedVar());
630 mprCreatePropertyValue(obj, "true", mprCreateBoolVar(1));
631 mprCreatePropertyValue(obj, "false", mprCreateBoolVar(0));
632 mprCreatePropertyValue(obj, "NULL", mprCreatePtrVar(NULL));
634 #if BLD_FEATURE_LEGACY_API
637 * So that ESP/ASP can ignore "language=javascript" statements
639 mprCreatePropertyValue(obj, "javascript", mprCreateIntegerVar(0));
643 * Extension functions
645 mprCreatePropertyValue(obj, "assert",
646 mprCreateCFunctionVar(assertProc, 0, MPR_VAR_SCRIPT_HANDLE));
647 mprCreatePropertyValue(obj, "eval",
648 mprCreateCFunctionVar(evalScriptProc, 0, MPR_VAR_SCRIPT_HANDLE));
649 mprCreatePropertyValue(obj, "exit",
650 mprCreateCFunctionVar(exitProc, 0, MPR_VAR_SCRIPT_HANDLE));
651 mprCreatePropertyValue(obj, "refCount",
652 mprCreateCFunctionVar(refCountProc, 0, MPR_VAR_SCRIPT_HANDLE));
653 mprCreatePropertyValue(obj, "print",
654 mprCreateCFunctionVar(printProc, 0, MPR_VAR_SCRIPT_HANDLE));
655 mprCreatePropertyValue(obj, "println",
656 mprCreateCFunctionVar(printlnProc, 0, MPR_VAR_SCRIPT_HANDLE));
657 mprCreatePropertyValue(obj, "printVars",
658 mprCreateCFunctionVar(printVarsProc,0, MPR_VAR_SCRIPT_HANDLE));
659 mprCreatePropertyValue(obj, "trace",
660 mprCreateStringCFunctionVar(traceProc, 0, MPR_VAR_SCRIPT_HANDLE));
665 mprCreatePropertyValue(obj, "Array",
666 mprCreateCFunctionVar(arrayConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
667 mprCreatePropertyValue(obj, "Boolean",
668 mprCreateCFunctionVar(booleanConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
669 mprCreatePropertyValue(obj, "Object",
670 mprCreateCFunctionVar(objectConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
671 mprCreatePropertyValue(obj, "Number",
672 mprCreateCFunctionVar(numberConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
673 mprCreatePropertyValue(obj, "String",
674 mprCreateCFunctionVar(stringConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
676 /* mprCreatePropertyValue(obj, "Date",
677 * mprCreateCFunctionVar(dateConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
678 * mprCreatePropertyValue(obj, "Regexp",
679 * mprCreateCFunctionVar(regexpConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
683 * Can we use on var x = "string text";
688 /******************************************************************************/
691 void ejsProcsDummy() {}
693 /******************************************************************************/
694 #endif /* BLD_FEATURE_EJS */
702 * vim600: sw=4 ts=4 fdm=marker