diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-09-16 18:05:53 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-09-16 18:05:53 +0200 |
commit | 197870a731f18dd9759e9cc97dfd298fda773251 (patch) | |
tree | 7d6ff05bc404d07d02bab47e59429986d47c842c /source4/lib/appweb/ejs-2.0/ejs | |
parent | c2eb4e5f8e0275003f9cffe1feeee6e34b7e578e (diff) | |
download | samba-197870a731f18dd9759e9cc97dfd298fda773251.tar.gz samba-197870a731f18dd9759e9cc97dfd298fda773251.tar.bz2 samba-197870a731f18dd9759e9cc97dfd298fda773251.zip |
Remove remaining embedded JavaScript support.
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/ejs')
44 files changed, 0 insertions, 22116 deletions
diff --git a/source4/lib/appweb/ejs-2.0/ejs/.ignore b/source4/lib/appweb/ejs-2.0/ejs/.ignore deleted file mode 100644 index 47f4ac63b2..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/.ignore +++ /dev/null @@ -1,2 +0,0 @@ -ejs -future diff --git a/source4/lib/appweb/ejs-2.0/ejs/Makefile b/source4/lib/appweb/ejs-2.0/ejs/Makefile deleted file mode 100644 index ea6be8c401..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -# -# Makefile for Embedded Javascript (EJS) -# -# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. -# - -# -# Ejs may be linked into shared handlers so we must build the objects both -# shared and static if --shared was specified to configure. -# -COMPILE := *.c -EXPORT_OBJECTS := yes -PRE_DIRS := classes system db -MAKE_IFLAGS := -I../mpr -I../exml - -include make.dep - -ifeq ($(BLD_PRODUCT),ejs) -POST_DIRS := package -endif - -ifeq ($(BLD_FEATURE_TEST),1) -POST_DIRS += test -endif - -ifeq ($(BLD_FEATURE_EJS_DB),1) -LIBS += sqlite -endif - -TARGETS += $(BLD_BIN_DIR)/libejs$(BLD_LIB) -TARGETS += $(BLD_BIN_DIR)/ejs$(BLD_EXE) - -ifeq ($(BLD_FEATURE_EJS),1) -compileExtra: $(TARGETS) -endif - -$(BLD_BIN_DIR)/libejs$(BLD_LIB): files \ - $(shell BLD_OBJ=$(BLD_OBJ) \; BLD_OBJ_DIR=$(BLD_OBJ_DIR) \; \ - eval echo `cat files`) - @bld --library $(BLD_BIN_DIR)/libejs \ - --objectsDir $(BLD_OBJ_DIR) --objectList files \ - --libs "exml mpr $(LIBS)" - -$(BLD_BIN_DIR)/ejs$(BLD_EXE): $(BLD_BIN_DIR)/libejs$(BLD_LIB) \ - $(BLD_BIN_DIR)/libmpr$(BLD_LIB) \ - $(BLD_BIN_DIR)/libejs$(BLD_LIB) $(FILES) - @bld --executable $(BLD_BIN_DIR)/ejs$(BLD_EXE) \ - --rpath "$(BLD_PREFIX)/bin" \ - --preferStatic --smartLibs "ejs exml mpr $(LIBS)" \ - --objectsDir $(BLD_OBJ_DIR) \ - --objects "$(BLD_OBJ_DIR)/ejsCmd$(BLD_OBJ)" - -cleanExtra: - @echo "rm -f $(TARGETS)" | $(BLDOUT) - @rm -f $(TARGETS) - @rm -f $(BLD_BIN_DIR)/libejs.* - -## Local variables: -## tab-width: 4 -## End: -## vim: tw=78 sw=4 ts=4 diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/.ignore b/source4/lib/appweb/ejs-2.0/ejs/classes/.ignore deleted file mode 100644 index fb5a29031e..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/.ignore +++ /dev/null @@ -1 +0,0 @@ -.updated diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/Makefile b/source4/lib/appweb/ejs-2.0/ejs/classes/Makefile deleted file mode 100644 index ce12bb3829..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# Makefile to build the EJS Classes -# -# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. -# - -COMPILE := *.c -EXPORT_OBJECTS := yes -MAKE_IFLAGS := -I.. -I../../mpr -I../../exml - -include make.dep - -compileExtra: .updated - -.updated: $(FILES) - @touch .updated - -## Local variables: -## tab-width: 4 -## End: -## vim: tw=78 sw=4 ts=4 diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsArray.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsArray.c deleted file mode 100644 index feb64b1aa8..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsArray.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * @file ejsArray.c - * @brief Array class - */ -/********************************* 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 ************************************/ - -int ejsDefineArrayClass(Ejs *ep) -{ - if (ejsDefineClass(ep, "Array", "Object", ejsArrayConstructor) == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - return 0; -} - -/******************************************************************************/ -/* - * Routine to create the base array type - */ - -EjsVar *ejsCreateArrayInternal(EJS_LOC_DEC(ep, loc), int size) -{ - EjsProperty *pp; - EjsVar *obj, *vp; - - /* MOB -- need to supply hash size -- max(size, 503)); */ - - obj = ejsCreateSimpleObjInternal(EJS_LOC_PASS(ep, loc), "Array"); - if (obj == 0) { - mprAssert(0); - return obj; - } - obj->isArray = 1; - - /* MOB -- call constructor here and replace this code */ - - pp = ejsSetPropertyToInteger(ep, obj, "length", size); - ejsMakePropertyEnumerable(pp, 0); - - vp = ejsGetVarPtr(pp); - vp->isArrayLength = 1; - - return obj; -} - -/******************************************************************************/ - -EjsVar *ejsAddArrayElt(Ejs *ep, EjsVar *op, EjsVar *element, - EjsCopyDepth copyDepth) -{ - EjsProperty *pp; - EjsVar *vp; - char idx[16]; - int length; - - mprAssert(op->isArray); - - length = ejsGetPropertyAsInteger(ep, op, "length"); - - mprItoa(idx, sizeof(idx), length); - pp = ejsCreateProperty(ep, op, idx); - vp = ejsGetVarPtr(pp); - - ejsWriteVar(ep, vp, element, copyDepth); - - ejsSetPropertyToInteger(ep, op, "length", length + 1); - - return vp; -} - -/******************************************************************************/ -/* - * Constructor - */ - -int ejsArrayConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsProperty *pp; - EjsVar *vp; - char idx[16]; - int i, max; - - thisObj->isArray = 1; - max = 0; - - if (argc > 0) { - if (argc == 1 && ejsVarIsNumber(argv[0])) { - /* - * x = new Array(size); - */ - max = (int) ejsVarToInteger(argv[0]); - - } else { - /* - * x = new Array(element0, element1, ..., elementN): - */ - max = argc; - for (i = 0; i < max; i++) { - mprItoa(idx, sizeof(idx), i); - pp = ejsCreateSimpleProperty(ep, thisObj, idx); - vp = ejsGetVarPtr(pp); - ejsWriteVar(ep, vp, argv[i], EJS_SHALLOW_COPY); - } - } - } - - pp = ejsCreateSimpleProperty(ep, thisObj, "length"); - ejsMakePropertyEnumerable(pp, 0); - vp = ejsGetVarPtr(pp); - ejsWriteVarAsInteger(ep, vp, max); - vp->isArrayLength = 1; - - return 0; -} - -/******************************************************************************/ - -#else -void ejsArrayDummy() {} - -/******************************************************************************/ -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsDate.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsDate.c deleted file mode 100755 index 096316a822..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsDate.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * @file ejsStndClasses.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 && 0 - -/******************************************************************************/ -/* - * Date constructor - - * - * Date(); - * Date(milliseconds); - * Date(dateString); - * Date(year, month, date); - * Date(year, month, date, hour, minute, second); - */ - -int ejsDateConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - return 0; -} - -/******************************************************************************/ - -static int load(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - const char *fileName; - XmlState *parser; - Exml *xp; - MprFile *file; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ep, EJS_ARG_ERROR, "Bad args. Usage: load(fileName);"); - return -1; - } - fileName = argv[0]->string; - - /* FUTURE -- not romable - Need rom code in MPR not MprServices - */ - file = mprOpen(ep, fileName, O_RDONLY, 0664); - if (file == 0) { - ejsError(ep, EJS_IO_ERROR, "Can't open: %s", fileName); - return -1; - } - - xp = initParser(ep, thisObj, fileName); - parser = exmlGetParseArg(xp); - - exmlSetInputStream(xp, readFileData, (void*) file); - - if (exmlParse(xp) < 0) { - if (! ejsGotException(ep)) { - ejsError(ep, EJS_IO_ERROR, "Can't parse XML file: %s\nDetails %s", - fileName, exmlGetErrorMsg(xp)); - } - termParser(xp); - mprClose(file); - return -1; - } - - ejsSetReturnValue(ep, parser->nodeStack[0].obj); - - termParser(xp); - mprClose(file); - - return 0; -} - -/******************************************************************************/ - -int ejsDefineDateClass(Ejs *ep) -{ - EjsVar *dateClass; - - dateClass = ejsDefineClass(ep, "Date", "Object", ejsDateConstructor); - if (dateClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - ejsDefineCMethod(ep, dateClass, "getDate", xxxProc, EJS_NO_LOCAL); - - /* Returns "Friday" or 4 ? */ - ejsDefineCMethod(ep, dateClass, "getDay", xxxProc, EJS_NO_LOCAL); - - ejsDefineCMethod(ep, dateClass, "getMonth", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "getFullYear", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "getYear", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "getHours", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "getMinutes", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "getSeconds", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "getMilliseconds", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "getTime", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "getTimeZoneOffset", xxxProc, EJS_NO_LOCAL); - - ejsDefineCMethod(ep, dateClass, "parse", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "setDate", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "setMonth", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "setFullYear", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "setYear", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "setMinutes", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "setSeconds", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "setMilliseconds", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "setTime", xxxProc, EJS_NO_LOCAL); - - ejsDefineCMethod(ep, dateClass, "toString", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "toGMTString", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "toUTCString", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "toLocaleString", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "UTC", xxxProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, dateClass, "valueOf", xxxProc, EJS_NO_LOCAL); - /* - UTC: getUTCDate, getUTCDay, getUTCMonth, getUTCFullYear, getUTCHours, - getUTCMinutes, getUTCSeconds, getUTCMilliseconds - setUTCDate, setUTCDay, setUTCMonth, setUTCFullYear, setUTCHours, - setUTCMinutes, setUTCSeconds, setUTCMilliseconds - */ - - return ejsObjHasErrors(dateClass) ? MPR_ERR_CANT_INITIALIZE : 0; -} - -/******************************************************************************/ -/* - Time is since 1970/01/01 GMT - - Normal: Fri Feb 10 2006 05:06:44 GMT-0800 (Pacific Standard Time) - UTC: Sat, 11 Feb 2006 05:06:44 GMT - - // Using without New - - println(Date()); - - var myDate = new Date(); - myDate.setFullYear(2010, 0, 14); - - var today = new Date(); - - if (myDate > today) { - } else { - } - - - X=Date() should be equivalent to X=(new Date()).toString() - - */ -/******************************************************************************/ - -#else -void ejsStndClassesDummy() {} - -/******************************************************************************/ -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsError.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsError.c deleted file mode 100755 index 99445afc7c..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsError.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * @file ejsError.c - * @brief Error class - */ -/********************************* 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 ************************************/ -/* - * Parse the args and return the message. Convert non-string args using - * .toString. - */ - -static char *getMessage(Ejs *ep, int argc, EjsVar **argv) -{ - if (argc == 0) { - return ""; - - } else if (argc == 1) { - if (! ejsVarIsString(argv[0])) { - if (ejsRunMethod(ep, argv[0], "toString", 0) < 0) { - return 0; - } - return ep->result->string; - - } else { - return argv[0]->string; - } - - } else { - /* Don't call ejsError here or it will go recursive. */ - return 0; - } -} - - -/******************************************************************************/ -/* - * Error Constructor and also used for constructor for sub classes. - * - * Usage: new Error([message]) - */ - -int ejsErrorCons(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - char *msg, *stack; - - msg = getMessage(ep, argc, argv); - if (msg == 0) { - return -1; - } - - ejsSetPropertyToString(ep, thisObj, "name", ejsGetBaseClassName(thisObj)); - ejsSetPropertyToString(ep, thisObj, "message", msg); - - ejsSetPropertyToUndefined(ep, thisObj, "stack"); - - stack = ejsFormatStack(ep); - if (stack) { - ejsSetPropertyToString(ep, thisObj, "stack", stack); - mprFree(stack); - } - - if (ejsObjHasErrors(thisObj)) { - return -1; - } - - return 0; -} - -/******************************************************************************/ - -int ejsDefineErrorClasses(Ejs *ep) -{ - if (ejsDefineClass(ep, "Error", "Object", ejsErrorCons) == 0 || - ejsDefineClass(ep, "AssertError", "Error", ejsErrorCons) == 0 || - ejsDefineClass(ep, "EvalError", "Error", ejsErrorCons) == 0 || - ejsDefineClass(ep, "InternalError", "Error", ejsErrorCons) == 0 || - ejsDefineClass(ep, "IOError", "Error", ejsErrorCons) == 0 || - ejsDefineClass(ep, "MemoryError", "Error", ejsErrorCons) == 0 || - ejsDefineClass(ep, "RangeError", "Error", ejsErrorCons) == 0 || - ejsDefineClass(ep, "ReferenceError", "Error", ejsErrorCons) == 0 || - ejsDefineClass(ep, "SyntaxError", "Error", ejsErrorCons) == 0 || - ejsDefineClass(ep, "TypeError", "Error", ejsErrorCons) == 0) { - - return MPR_ERR_CANT_INITIALIZE; - } - return 0; -} - -/******************************************************************************/ - -#else -void ejsErrorDummy() {} - -/******************************************************************************/ -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsObject.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsObject.c deleted file mode 100644 index 4f2e23beb2..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsObject.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * @file ejsObject.c - * @brief Object class - */ -/********************************* 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 - -/****************************** Forward Declarations **************************/ -/* - * Support routines - */ - -static void formatVar(Ejs *ep, MprBuf *bp, EjsVar *vp); - -/******************************************************************************/ -/* - * Routine to create an object of the desired class. Class name may - * contain "." - * - * The created object will be a stand-alone class NOT entered into the - * properties of any other object. Callers must do this if required. ClassName - * may contain "." and is interpreted relative to "obj" if supplied. - * - * Note: this does not call the constructors for the various objects and base - * classes. - */ - -EjsVar *ejsCreateSimpleObjInternal(EJS_LOC_DEC(ep, loc), const char *className) -{ - EjsVar *baseClass; - - if (className && *className) { - baseClass = ejsGetClass(ep, 0, className); - if (baseClass == 0) { - mprError(ep, MPR_LOC, "Can't find base class %s", className); - return 0; - } - } else { - baseClass = 0; - } - - return ejsCreateSimpleObjUsingClassInt(EJS_LOC_PASS(ep, loc), - baseClass); -} - -/******************************************************************************/ -/* - * Create an object based upon the specified base class object. It will be a - * stand-alone class not entered into the properties of any other object. - * Callers must do this if required. - * - * Note: this does not call the constructors for the various objects and base - * classes. - */ - -EjsVar *ejsCreateSimpleObjUsingClassInt(EJS_LOC_DEC(ep, loc), - EjsVar *baseClass) -{ - EjsVar *vp; - - mprAssert(baseClass); - - if (baseClass == 0) { - mprError(ep, MPR_LOC, "Missing base class\n"); - return 0; - } - - vp = ejsCreateObjVarInternal(EJS_LOC_PASS(ep, loc)); - if (vp == 0) { - return vp; - } - - ejsSetBaseClass(vp, baseClass); - - /* - * This makes all internal method accesses faster - * NOTE: this code is duplicated in ejsCreateSimpleClass - */ - mprAssert(vp->objectState); - vp->objectState->methods = baseClass->objectState->methods; - - return vp; -} - -/******************************************************************************/ - -void ejsSetMethods(Ejs *ep, EjsVar *op) -{ - op->objectState->methods = ep->global->objectState->methods; -} - -/******************************************************************************/ -/******************************** Internal Methods ****************************/ -/******************************************************************************/ - -static EjsVar *createObjProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - return ejsGetVarPtr(ejsCreateSimpleProperty(ep, obj, property)); -} - -/******************************************************************************/ - -static int deleteObjProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - return ejsDeleteProperty(ep, obj, property); -} - -/******************************************************************************/ - -static EjsVar *getObjProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - return ejsGetVarPtr(ejsGetSimpleProperty(ep, obj, property)); -} - -/******************************************************************************/ -/* - * Set the value of a property. Create if it does not exist - */ - -static EjsVar *setObjProperty(Ejs *ep, EjsVar *obj, const char *property, - const EjsVar *value) -{ - EjsProperty *pp; - EjsVar *vp; - - pp = ejsCreateSimpleProperty(ep, obj, property); - if (pp == 0) { - mprAssert(pp); - return 0; - } - vp = ejsGetVarPtr(pp); - if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) < 0) { - mprAssert(0); - return 0; - } - return ejsGetVarPtr(pp); -} - -/******************************************************************************/ -/*********************************** Constructors *****************************/ -/******************************************************************************/ -#if UNUSED -/* - * Object constructor. We don't use this for speed. Think very carefully if - * you add an object constructor. - */ - -int ejsObjectConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - return 0; -} - -#endif -/******************************************************************************/ -/******************************** Visible Methods *****************************/ -/******************************************************************************/ - -static int cloneMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int copyDepth; - - copyDepth = EJS_DEEP_COPY; - - if (argc == 1 && ejsVarToBoolean(argv[0])) { - copyDepth = EJS_RECURSIVE_DEEP_COPY; - } - - ejsWriteVar(ep, ep->result, thisObj, copyDepth); - - return 0; -} - -/******************************************************************************/ - -static int toStringMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprBuf *bp; - int saveMaxDepth, saveDepth, saveFlags; - - saveMaxDepth = ep->maxDepth; - - if (argc >= 1) { - ep->maxDepth = ejsVarToInteger(argv[0]); - } else if (ep->maxDepth == 0) { - ep->maxDepth = MAXINT; - } - - saveFlags = ep->flags; - if (argc >= 2) { - if (ejsVarToBoolean(argv[1])) { - ep->flags |= EJS_FLAGS_ENUM_HIDDEN; - } - } - if (argc == 3) { - if (ejsVarToBoolean(argv[2])) { - ep->flags |= EJS_FLAGS_ENUM_BASE; - } - } - - bp = mprCreateBuf(ep, 0, 0); - - saveDepth = ep->depth; - - formatVar(ep, bp, thisObj); - - ep->depth = saveDepth; - ep->maxDepth = saveMaxDepth; - - mprAddNullToBuf(bp); - - ejsWriteVarAsString(ep, ep->result, mprGetBufStart(bp)); - mprFree(bp); - - ep->flags = saveFlags; - - return 0; -} - -/******************************************************************************/ - -static int valueOfMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 0) { - mprAssert(0); - return -1; - } - - switch (thisObj->type) { - default: - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - case EJS_TYPE_CMETHOD: - case EJS_TYPE_OBJECT: - case EJS_TYPE_METHOD: - case EJS_TYPE_STRING_CMETHOD: - ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY); - break; - - case EJS_TYPE_STRING: - ejsWriteVarAsInteger(ep, ep->result, atoi(thisObj->string)); - break; - - case EJS_TYPE_BOOL: - case EJS_TYPE_INT: -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: -#endif -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: -#endif - ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY); - break; - } - return 0; -} - -/******************************************************************************/ - -static int hashGetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToInteger(ejs, (int) thisObj->objectState); - return 0; -} - -/******************************************************************************/ - -static int classGetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (thisObj->objectState == 0 || thisObj->objectState->baseClass == 0) { - ejsSetReturnValueToString(ejs, "object"); - } else { - ejsSetReturnValueToString(ejs, - thisObj->objectState->baseClass->objectState->className); - } - return 0; -} - -/******************************************************************************/ -/* - * Format an object. Called recursively to format properties and contained - * objects. - */ - -static void formatVar(Ejs *ep, MprBuf *bp, EjsVar *vp) -{ - EjsProperty *pp, *first; - EjsVar *propVar, *baseClass; - char *buf, *value; - int i; - - if (vp->type == EJS_TYPE_OBJECT) { - if (!vp->objectState->visited) { - - mprPutStringToBuf(bp, vp->isArray ? "[\n" : "{\n"); - - ep->depth++; - vp->objectState->visited = 1; - - if (ep->depth <= ep->maxDepth) { - first = ejsGetFirstProperty(vp, EJS_ENUM_ALL); - - if (ep->flags & EJS_FLAGS_ENUM_BASE) { - baseClass = vp->objectState->baseClass; - if (baseClass) { - for (i = 0; i < ep->depth; i++) { - mprPutStringToBuf(bp, " "); - } - mprPutStringToBuf(bp, baseClass->objectState->objName); - mprPutStringToBuf(bp, ": /* Base Class */ "); - if (baseClass->objectState == vp->objectState) { - value = "this"; - } else if (ejsRunMethodCmd(ep, baseClass, "toString", - "%d", ep->maxDepth) < 0) { - value = "[object Object]"; - } else { - mprAssert(ejsVarIsString(ep->result)); - value = ep->result->string; - } - mprPutStringToBuf(bp, value); - if (first) { - mprPutStringToBuf(bp, ",\n"); - } - } - } - - pp = first; - while (pp) { - if (! pp->dontEnumerate || - ep->flags & EJS_FLAGS_ENUM_HIDDEN) { - for (i = 0; i < ep->depth; i++) { - mprPutStringToBuf(bp, " "); - } - - if (! vp->isArray) { - mprPutStringToBuf(bp, pp->name); - mprPutStringToBuf(bp, ": "); - } - - propVar = ejsGetVarPtr(pp); - if (propVar->type == EJS_TYPE_OBJECT) { - if (pp->var.objectState == vp->objectState) { - value = "this"; - } else if (ejsRunMethodCmd(ep, propVar, - "toString", "%d", ep->maxDepth) < 0) { - value = "[object Object]"; - } else { - mprAssert(ejsVarIsString(ep->result)); - value = ep->result->string; - } - mprPutStringToBuf(bp, value); - - } else { - formatVar(ep, bp, &pp->var); - } - - pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); - if (pp) { - mprPutStringToBuf(bp, ",\n"); - } - } else { - pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); - } - } - } - vp->objectState->visited = 0; - - mprPutCharToBuf(bp, '\n'); - - ep->depth--; - for (i = 0; i < ep->depth; i++) { - mprPutStringToBuf(bp, " "); - } - mprPutCharToBuf(bp, vp->isArray ? ']' : '}'); - } - - } else if (vp->type == EJS_TYPE_METHOD) { - - mprPutStringToBuf(bp, "function ("); - for (i = 0; i < vp->method.args->length; i++) { - mprPutStringToBuf(bp, vp->method.args->items[i]); - if ((i + 1) < vp->method.args->length) { - mprPutStringToBuf(bp, ", "); - } - } - mprPutStringToBuf(bp, ") {"); - mprPutStringToBuf(bp, vp->method.body); - for (i = 0; i < ep->depth; i++) { - mprPutStringToBuf(bp, " "); - } - mprPutStringToBuf(bp, "}"); - - } else { - - if (vp->type == EJS_TYPE_STRING) { - mprPutCharToBuf(bp, '\"'); - } - - /* - * We don't use ejsVarToString for arrays, objects and strings. - * This is because ejsVarToString does not call "obj.toString" - * and it is not required for strings. - * MOB - rc - */ - buf = ejsVarToString(ep, vp); - mprPutStringToBuf(bp, buf); - - if (vp->type == EJS_TYPE_STRING) { - mprPutCharToBuf(bp, '\"'); - } - } -} - -/******************************************************************************/ -/* - * mixin code. Blends code at the "thisObj" level. - */ - -static int mixinMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsProperty *pp; - char *buf; - int fid, i, rc; - - mprAssert(argv); - - /* - * Create a variable scope block set to the current object - */ - rc = 0; - fid = ejsSetBlock(ep, thisObj); - - for (i = 0; i < argc; i++) { - - if (ejsVarIsString(argv[i])) { - rc = ejsEvalScript(ep, argv[i]->string, 0); - - } else if (ejsVarIsObject(argv[i])) { - - /* MOB -- OPT. When we have proper scope chains, we should just - refer to the module and not copy */ - pp = ejsGetFirstProperty(argv[i], EJS_ENUM_ALL); - while (pp) { - ejsSetProperty(ep, thisObj, pp->name, ejsGetVarPtr(pp)); - pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); - } - - } else { - /* MOB - rc */ - buf = ejsVarToString(ep, argv[i]); - rc = ejsEvalScript(ep, buf, 0); - - } - if (rc < 0) { - ejsCloseBlock(ep, fid); - return -1; - } - } - ejsCloseBlock(ep, fid); - return 0; -} - -/******************************************************************************/ -/* - * Create the object class - */ - -int ejsDefineObjectClass(Ejs *ep) -{ - EjsMethods *methods; - EjsProperty *objectProp, *protoProp; - EjsVar *op, *globalClass; - - /* - * Must specially hand-craft the object class as it is the base class - * of all objects. - */ - op = ejsCreateObjVar(ep); - if (op == 0) { - return MPR_ERR_CANT_CREATE; - } - ejsSetClassName(ep, op, "Object"); - - /* - * Don't use a constructor for objects for speed - */ - ejsMakeClassNoConstructor(op); - - /* - * MOB -- should mark properties as public / private and class or instance. - */ - ejsDefineCMethod(ep, op, "clone", cloneMethod, EJS_NO_LOCAL); - ejsDefineCMethod(ep, op, "toString", toStringMethod, EJS_NO_LOCAL); - ejsDefineCMethod(ep, op, "valueOf", valueOfMethod, EJS_NO_LOCAL); - ejsDefineCMethod(ep, op, "mixin", mixinMethod, EJS_NO_LOCAL); - - ejsDefineCAccessors(ep, op, "hash", hashGetAccessor, 0, EJS_NO_LOCAL); - ejsDefineCAccessors(ep, op, "baseClass", classGetAccessor, 0, EJS_NO_LOCAL); - - /* - * MOB -- make this an accessor - */ - protoProp = ejsSetProperty(ep, op, "prototype", op); - if (protoProp == 0) { - ejsFreeVar(ep, op); - return MPR_ERR_CANT_CREATE; - } - - /* - * Setup the internal methods. Most classes will never override these. - * The XML class will. We rely on talloc to free internal. Use "ep" as - * the parent as we need "methods" to live while the interpreter lives. - */ - methods = mprAllocTypeZeroed(ep, EjsMethods); - op->objectState->methods = methods; - - methods->createProperty = createObjProperty; - methods->deleteProperty = deleteObjProperty; - methods->getProperty = getObjProperty; - methods->setProperty = setObjProperty; - - objectProp = ejsSetPropertyAndFree(ep, ep->global, "Object", op); - - /* - * Change the global class to use Object's methods - */ - globalClass = ep->service->globalClass; - globalClass->objectState->methods = methods; - globalClass->objectState->baseClass = ejsGetVarPtr(protoProp); - - ep->objectClass = ejsGetVarPtr(objectProp); - - if (ejsObjHasErrors(ejsGetVarPtr(objectProp))) { - ejsFreeVar(ep, op); - return MPR_ERR_CANT_CREATE; - } - return 0; -} - -/******************************************************************************/ - -#else -void ejsObjectDummy() {} - -/******************************************************************************/ -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsStndClasses.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsStndClasses.c deleted file mode 100644 index fd6cda7813..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsStndClasses.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * @file ejsStndClasses.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 - -/******************************************************************************/ -/******************************* Function Class *******************************/ -/******************************************************************************/ - -int ejsDefineFunctionClass(Ejs *ep) -{ - if (ejsDefineClass(ep, "Function", "Object", ejsFunctionConstructor) == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - return 0; -} - -/******************************************************************************/ -/* - * Function constructor - */ - -int ejsFunctionConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsArgError(ep, "Usage: Function(\"function (arg) { script };\");"); - } - - rc = ejsEvalScript(ep, argv[0]->string, 0); - - /* - * Note: this will convert the object into a method. It will cease to be - * an object. - */ - if (rc == 0 && ejsVarIsMethod(ep->result)) { - /* - * Must make thisObj collectable. - */ - ejsMakeObjPermanent(thisObj, 0); - ejsMakeObjLive(thisObj, 1); - mprAssert(ejsObjIsCollectable(thisObj)); - ejsWriteVar(ep, thisObj, ep->result, EJS_SHALLOW_COPY); - } - return rc; -} - -/******************************************************************************/ -/******************************* Boolean Class ********************************/ -/******************************************************************************/ - -int ejsDefineBooleanClass(Ejs *ep) -{ - if (ejsDefineClass(ep, "Boolean", "Object", ejsBooleanConstructor) == 0){ - return MPR_ERR_CANT_INITIALIZE; - } - return 0; -} - -/******************************************************************************/ -/* - * Boolean constructor - */ - -int ejsBooleanConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - return 0; -} - -/******************************************************************************/ -/******************************** Number Class ********************************/ -/******************************************************************************/ - -int ejsDefineNumberClass(Ejs *ep) -{ - if (ejsDefineClass(ep, "Number", "Object", ejsNumberConstructor) == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - return 0; -} - -/******************************************************************************/ -/* - * Number constructor - */ - -int ejsNumberConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - return 0; -} - -/******************************************************************************/ - -#else -void ejsStndClassesDummy() {} - -/******************************************************************************/ -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsString.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsString.c deleted file mode 100644 index 2339650361..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsString.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * @file ejsString.c - * @brief EJScript string class - */ -/********************************* 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 -/******************************************************************************/ -/*********************************** Constructors *****************************/ -/******************************************************************************/ -/* - * String constructor. - */ - -int ejsStringConstructor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - char *str; - - if (argc == 0) { - ejsSetReturnValueToString(ejs, ""); - - } else if (argc == 1) { - /* MOB -- rc */ - str = ejsVarToString(ejs, argv[0]); - ejsSetReturnValueToString(ejs, str); - - } else { - ejsArgError(ejs, "usage: String([var])"); - return -1; - } - - return 0; -} - -/******************************************************************************/ -/******************************** Visible Methods *****************************/ -/******************************************************************************/ -/* - * Return a string containing the character at a given index - * - * String string.charAt(Number) - */ - -static int charAt(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsNum num; - char buf[2]; - - if (argc != 1) { - ejsArgError(ejs, "usage: charAt(integer)"); - return -1; - } - - num = ejsVarToNumber(argv[0]); - if (num < 0 || num >= thisObj->length) { - ejsError(ejs, EJS_RANGE_ERROR, "Bad index"); - return -1; - } - - mprAssert(ejsVarIsString(thisObj)); - - buf[0] = argv[0]->string[num]; - buf[1] = '\0'; - ejsSetReturnValueToString(ejs, buf); - - return 0; -} - -/******************************************************************************/ -/* - * Return an integer containing the character at a given index - * - * Number string.charCodeAt(Number) - */ - -static EjsNum charCodeAt(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsNum num; - - if (argc != 1) { - ejsArgError(ejs, "usage: charCodeAt(integer)"); - return -1; - } - - num = ejsVarToNumber(argv[0]); - if (num < 0 || num >= thisObj->length) { - ejsError(ejs, EJS_RANGE_ERROR, "Bad index"); - return -1; - } - ejsSetReturnValueToNumber(ejs, (EjsNum) argv[0]->string[num]); - - return 0; -} - -/******************************************************************************/ -/* - * Catenate - * - * String string.catenate(var, ...) - */ - -static int concat(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int i; - - if (argc == 0) { - ejsArgError(ejs, "usage: concat(String, ...)"); - return -1; - } - - mprAssert(ejsVarIsString(thisObj)); - - for (i = 0; i < argc; i++) { - if (ejsStrcat(ejs, thisObj, argv[i]) < 0) { - ejsMemoryError(ejs); - return -1; - } - } - ejsSetReturnValue(ejs, thisObj); - return 0; -} - -/******************************************************************************/ -/* - * Return the position of the first occurance of a substring - * - * Number string.indexOf(String subString [, Number start]) - */ - -static int indexOf(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - char *pat, *s1, *s2, *origin; - int start, i; - - if (argc == 0 || argc > 2) { - ejsArgError(ejs, "usage: indexOf(String [, Number])"); - return -1; - } - - pat = ejsVarToString(ejs, argv[0]); - - if (argc == 2) { - start = ejsVarToNumber(argv[1]); - if (start > thisObj->length) { - start = thisObj->length; - } - } else { - start = 0; - } - - i = start; - for (origin = &thisObj->string[i]; i < thisObj->length; i++, origin++) { - s1 = origin; - for (s2 = pat; *s1 && *s2; s1++, s2++) { - if (*s1 != *s2) { - break; - } - } - if (*s2 == '\0') { - ejsSetReturnValueToNumber(ejs, (EjsNum) (origin - thisObj->string)); - } - } - - ejsSetReturnValueToNumber(ejs, (EjsNum) -1); - return 0; -} - -/******************************************************************************/ -/* - * Return the position of the last occurance of a substring - * - * Number string.lastIndexOf(String subString [, Number start]) - */ - -static int lastIndexOf(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - char *pat, *s1, *s2, *origin; - int start; - - if (argc == 0 || argc > 2) { - ejsArgError(ejs, "usage: indexOf(String [, Number])"); - return -1; - } - - pat = ejsVarToString(ejs, argv[0]); - - if (argc == 2) { - start = ejsVarToNumber(argv[1]); - if (start > thisObj->length) { - start = thisObj->length; - } - } else { - start = 0; - } - - origin = &thisObj->string[thisObj->length - 1]; - for (; origin >= &thisObj->string[start]; origin--) { - - s1 = origin; - for (s2 = pat; *s1 && *s2; s1++, s2++) { - if (*s1 != *s2) { - break; - } - } - if (*s2 == '\0') { - ejsSetReturnValueToNumber(ejs, (EjsNum) (origin - thisObj->string)); - } - } - - ejsSetReturnValueToNumber(ejs, (EjsNum) -1); - return 0; -} - -/******************************************************************************/ -/* - * Return a substring - * - * Number string.slice(Number start, Number end) - */ - -static int slice(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsNum start, end; - - if (argc != 2) { - ejsArgError(ejs, "usage: slice(Number, Number)"); - return -1; - } - - start = ejsVarToNumber(argv[0]); - end = ejsVarToNumber(argv[1]); - if (start < 0 || start >= thisObj->length) { - ejsError(ejs, EJS_RANGE_ERROR, "Bad start index"); - return-1; - } - if (end < 0 || end >= thisObj->length) { - ejsError(ejs, EJS_RANGE_ERROR, "Bad end index"); - return -1; - } - - mprAssert(ejsVarIsString(thisObj)); - - ejsSetReturnValueToBinaryString(ejs, (uchar*) &thisObj->string[start], - end - start); - - return 0; -} - -/******************************************************************************/ -/* - * Split a string - * - * Number string.split(String delimiter [, Number limit]) - */ - -static int split(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsVar *array, *vp; - char *delim, *last, *cp; - int len, limit, alloc; - - if (argc == 0 || argc > 2) { - ejsArgError(ejs, "usage: split(String [, Number])"); - return -1; - } - - delim = ejsVarToStringEx(ejs, argv[0], &alloc); - - limit = ejsVarToNumber(argv[1]); - - array = ejsCreateArray(ejs, 0); - - len = strlen(delim); - - last = thisObj->string; - for (cp = last; *cp; cp++) { - if (*cp == *delim && strncmp(cp, delim, len) == 0) { - if (cp > last) { - vp = ejsCreateBinaryStringVar(ejs, (uchar*) last, (cp - last)); - ejsAddArrayElt(ejs, array, vp, EJS_SHALLOW_COPY); - ejsFreeVar(ejs, vp); - } - } - } - - ejsSetReturnValue(ejs, array); - ejsFreeVar(ejs, array); - - if (alloc) { - mprFree(delim); - } - - return 0; -} - -/******************************************************************************/ -/* - * Create the object class - */ - -int ejsDefineStringClass(Ejs *ejs) -{ - EjsVar *sc; - - sc = ejsDefineClass(ejs, "String", "Object", ejsStringConstructor); - if (sc == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - ejsDefineCMethod(ejs, sc, "charAt", charAt, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "charCodeAt", charCodeAt, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "concat", concat, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "indexOf", indexOf, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "lastIndexOf", lastIndexOf, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "slice", slice, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "split", split, EJS_NO_LOCAL); -#if UNUSED - ejsDefineCMethod(ejs, sc, "match", match, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "replace", replace, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "search", search, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "substring", substring, EJS_NO_LOCAL); - // MOB bad name - ejsDefineCMethod(ejs, sc, "substr", substr, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "toLowerCase", toLowerCase, EJS_NO_LOCAL); - ejsDefineCMethod(ejs, sc, "toUpperCase", toUpperCase, EJS_NO_LOCAL); - - // Static method - ejsDefineCMethod(ejs, sc, "fromCharCode", fromCharCode, 0, EJS_NO_LOCAL); -#endif - - if (ejsObjHasErrors(sc)) { - ejsFreeVar(ejs, sc); - return MPR_ERR_CANT_CREATE; - } - return 0; -} - -/******************************************************************************/ -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsXml.c b/source4/lib/appweb/ejs-2.0/ejs/classes/ejsXml.c deleted file mode 100644 index a2ef8d1390..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/classes/ejsXml.c +++ /dev/null @@ -1,1327 +0,0 @@ -/* - * @file ejsXml.c - * @brief E4X XML support - */ -/********************************* 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 - */ -/************************************ Doc *************************************/ -/* - * Javascript class definition - * - * class XML { - * public XML(); - * public XML(string xmlString); // "<tag... " - * public XML(string file); // "file" - * - * public void load(string file); - * public void save(string file); - * public Array children(); - * public Array attributes(); - * } - * - [[Internal Properties / Methods]] - - prototype - Ptr to class prototype (base class) - - class - Type of class - Object.prototype.toString - - Value - - - Get(name) - Returns the value - - Put(name, value) - Sets the value - - HasProperty(name) - Bool if property exists - - Delete(name) - Delete property - - DefaultValue(hint) - Return default primitive (not obj) value - toString, if result is obj, then call valueOf - if hint is number, then call valueOf, then toString - - Construct(arg list) - Constructor - - Call(arg list) - Function call - - HasInstance(value) - ?? - - Scope - Frame scope chain - - Match(string, index) - Regexp match - - - Example: - XML attribute @name - @* - * - var node = new XML("<order/>"); - Operators: - var prices = order..price; - var urgentItems = order.item(@level == "rush"); - var itemAttrs = order.item[0].@*; # @ for attributes - XML Literals - order.customer.address = - <address>..... - <zip>{zipCode}</zip> Where {var} is a JS var - <tag attribute={prefix}> ... Also for attributes - </address> - Omit namespaces - Example: - var html = <html/>; - html.head.title = "My title"; - head.body@bgcolor = "#e4e4e4"; -*/ - -/********************************** Includes **********************************/ - -#include "ejs.h" -#include "exml.h" - -/************************************ Data ************************************/ -#if BLD_FEATURE_EJS_E4X - -/* - * Per tag state - */ -typedef struct XmlTagState { - EjsVar *obj; - EjsVar *attributes; - EjsVar *comments; -} XmlTagState; - -/* - * Parser state - */ -typedef struct XmlState { - Ejs *ep; - EjsVar *xmlClass; - EjsVar *xmlListClass; - XmlTagState nodeStack[E4X_MAX_NODE_DEPTH]; - int topOfStack; - long inputSize; - long inputPos; - const char *inputBuf; - const char *fileName; -} XmlState; - -/****************************** Forward Declarations **************************/ -/* - * XML methods - */ -static int text(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int name(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int load(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int save(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int toString(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int valueOf(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); - -/* MOB -- temp */ -static int getList(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int setText(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); - -#if FUTURE -static int length(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int toXmlString(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); - -static int appendChild(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int attributes(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int child(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int children(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int comments(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int decendants(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int elements(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int insertChildAfter(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int insertChildBefore(Ejs *ep, EjsVar *thisObj, int argc, - EjsVar **argv); -static int replace(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int setName(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -static int text(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv); -#endif - -/* - * Internal methods - */ -static EjsVar *createXmlProperty(Ejs *ep, EjsVar *obj, const char *property); -static int deleteXmlProperty(Ejs *ep, EjsVar *obj, const char *property); -static EjsVar *getXmlProperty(Ejs *ep, EjsVar *obj, const char *property); -static EjsVar *setXmlProperty(Ejs *ep, EjsVar *obj, const char *property, - const EjsVar *value); -static int loadXmlString(Ejs *ep, EjsVar *thisObj, const char *xmlString); - -/* - * XMLList methods - */ -static EjsVar *createXmlListProperty(Ejs *ep, EjsVar *obj, - const char *property); -static int deleteXmlListProperty(Ejs *ep, EjsVar *obj, - const char *property); -static EjsVar *getXmlListProperty(Ejs *ep, EjsVar *obj, const char *property); -static EjsVar *setXmlListProperty(Ejs *ep, EjsVar *obj, const char *property, - const EjsVar *value); - -/* - * Misc - */ -static int readFileData(Exml *xp, void *data, char *buf, int size); -static int readStringData(Exml *xp, void *data, char *buf, int size); -static int parserHandler(Exml *xp, int state, const char *tagName, - const char *attName, const char *value); -static void termParser(Exml *xp); -static Exml *initParser(Ejs *ep, EjsVar *thisObj, const char *fileName); -static int getNumElements(EjsVar *obj); -static int getText(MprBuf *buf, EjsVar *obj); -static int xmlToString(Ejs *ep, MprBuf *buf, EjsVar *obj, int indentLevel); -static void indent(MprBuf *bp, int level); -static char *cleanTagName(char *name); - -/******************************************************************************/ -/* - * Define the E4X classes (XML, XMLList) - */ - -int ejsDefineXmlClasses(Ejs *ep) -{ - EjsMethods *methods; - EjsVar *xmlClass, *xmlListClass; - - /* - * Create the XML class - */ - xmlClass = ejsDefineClass(ep, "XML", "Object", ejsXmlConstructor); - if (xmlClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the XML class methods - */ - ejsDefineCMethod(ep, xmlClass, "text", text, EJS_NO_LOCAL); - ejsDefineCMethod(ep, xmlClass, "name", name, EJS_NO_LOCAL); - ejsDefineCMethod(ep, xmlClass, "load", load, EJS_NO_LOCAL); - ejsDefineCMethod(ep, xmlClass, "save", save, EJS_NO_LOCAL); - ejsDefineCMethod(ep, xmlClass, "toString", toString, EJS_NO_LOCAL); - ejsDefineCMethod(ep, xmlClass, "valueOf", valueOf, EJS_NO_LOCAL); - -/* MOB -- temporary only */ - ejsDefineCMethod(ep, xmlClass, "getList", getList, EJS_NO_LOCAL); - ejsDefineCMethod(ep, xmlClass, "setText", setText, EJS_NO_LOCAL); - - /* - * Setup the XML internal methods. - */ - methods = mprAllocTypeZeroed(ep, EjsMethods); - xmlClass->objectState->methods = methods; - - methods->createProperty = createXmlProperty; - methods->deleteProperty = deleteXmlProperty; - methods->getProperty = getXmlProperty; - methods->setProperty = setXmlProperty; - - /* - * Create the XMLList class - */ - xmlListClass = ejsDefineClass(ep, "XMLList", "Array", - ejsXmlListConstructor); - - /* - * Define the XMLList class methods - */ - - /* - * Setup the XML internal methods. - */ - methods = mprAllocTypeZeroed(ep, EjsMethods); - xmlListClass->objectState->methods = methods; - - methods->createProperty = createXmlListProperty; - methods->deleteProperty = deleteXmlListProperty; - methods->getProperty = getXmlListProperty; - methods->setProperty = setXmlListProperty; - - /* MOB -- need to complete xmlListClass */ - - return (ejsObjHasErrors(xmlClass) || ejsObjHasErrors(xmlListClass)) - ? MPR_ERR_CANT_INITIALIZE : 0; - return 0; -} - -/******************************************************************************/ -/* - * Routine to create an XML object using a default constructor - */ - -EjsVar *ejsCreateXml(Ejs *ep) -{ - EjsVar *op; - - op = ejsCreateSimpleObj(ep, "XML"); - if (op == 0) { - mprAssert(op); - return op; - } - ejsSetVarName(ep, op, "xmlNode"); - - /* - * Invoke class constructors manually (for speed and space) - */ - if (ejsXmlConstructor(ep, op, 0, 0) < 0) { - mprFree(op); - mprAssert(0); - return 0; - } - return op; -} - -/******************************************************************************/ -/* - * XML constructor - */ - -int ejsXmlConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsVar *vp; - const char *str; - - ejsSetVarFlags(thisObj, EJS_XML_FLAGS_ELEMENT); - - if (argc == 1) { - vp = argv[0]; - - if (ejsVarIsObject(vp)) { - /* Convert DOM to XML. Not implemented */; - - } else if (ejsVarIsString(vp)) { - str = vp->string; - if (str == 0) { - return 0; - } - if (*str == '<') { - /* XML Literal */ - return loadXmlString(ep, thisObj, str); - - } else { - /* Load from file */ - return load(ep, thisObj, argc, argv); - } - } else { - ejsError(ep, EJS_TYPE_ERROR, "Bad type passed to XML constructor"); - return -1; - } - } - return 0; -} - -/******************************************************************************/ -/* - * Routine to create an XMLList object - */ - -EjsVar *ejsCreateXmlList(Ejs *ep) -{ - EjsVar *op; - - /* Sanity limit for size of hash table */ - - op = ejsCreateSimpleObj(ep, "XMLList"); - if (op == 0) { - mprAssert(0); - return op; - } - if (ejsArrayConstructor(ep, op, 0, 0) < 0 || - ejsXmlConstructor(ep, op, 0, 0) < 0) { - mprFree(op); - mprAssert(0); - return 0; - } - return op; -} - -/******************************************************************************/ -/* - * XMLList constructor - */ - -int ejsXmlListConstructor(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - // ejsSetVarFlags(vp, EJS_XML_FLAGS_ELEMENT); - return 0; -} - -/******************************************************************************/ -/******************************** Internal Methods ****************************/ -/******************************************************************************/ - -static EjsVar *createXmlProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - return ejsGetVarPtr(ejsCreateSimpleProperty(ep, obj, property)); -} - -/******************************************************************************/ - -static int deleteXmlProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - return ejsDeleteProperty(ep, obj, property); -} - -/******************************************************************************/ -/* MOB -- need ep as an arg */ -static EjsVar *getXmlProperty(Ejs *ep, EjsVar *obj, const char *property) -{ -#if NEW - EjsVar *lp; - - lp = ejsCreateXmlList(ep); - if (isdigit(*property)) { - /* MOB -- where do we store these. Do we need them ? */ - lp->targetObject = obj - lp->targetProperty = property - return getXmlListProperty(lp, property); - } - - /* What about a simple elment. Should it not return the text */ - - if (*property == '@') { - ap = ejsGetFirstProperty(obj, EJS_ENUM_ALL); - while (ap) { - vp = ejsGetVarPtr(ap); - /* MOB -- are attributes unique ? */ - if (vp->flags & EJS_XML_FLAGS_ATTRIBUTE && - strcmp(property, ap->name) == 0) { - ejsAppendXml(lp, vp); - } - ap = ejsGetNexttProperty(ap, EJS_ENUM_ALL); - } - } else { - while (ap) { - vp = ejsGetVarPtr(ap); - /* MOB -- are attributes unique ? */ - if (vp->flags & EJS_XML_FLAGS_ELEMENT && - strcmp(property, ap->name) == 0) { - ejsAppendXml(lp, vp); - } - ap = ejsGetNexttProperty(ap, EJS_ENUM_ALL); - } - } - return l; - - // Must always return XML or XMLList event for comments and attributes -#endif - return ejsGetVarPtr(ejsGetSimpleProperty(ep, obj, property)); -} - -/******************************************************************************/ - -static EjsVar *setXmlProperty(Ejs *ep, EjsVar *obj, const char *property, - const EjsVar *value) -{ - EjsProperty *pp; - EjsVar *vp; - - pp = ejsCreateSimpleProperty(ep, obj, property); - if (pp == 0) { - /* Should never happen */ - mprAssert(pp); - return 0; - } - vp = ejsGetVarPtr(pp); - if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) < 0) { - return 0; - } - return ejsGetVarPtr(pp); -} - -/******************************************************************************/ -/* - NEW - -static EjsVar *setXmlProperty(Ejs *ep, EjsVar *op, const char *property, - EjsVar *value) -{ - - if ((value->objectState->baseClass != XML && - value->objectState->baseClass != XMLList) || - value->string[0] != '<') { - ejsVarToString(luevalue.toString(); - ejsRunMethod(ep, value, "toString", 0); - value = ejsDupVar(ep->result); - - } else { - value = ejsDupVar(value); - } - - if (isdigit(*property)) { - // ERROR -- reserved for future versions - return 0; - } - - if (*property == '@') { - if (op->objectState->baseClass == XMLList) { - if (op->obj.LENGTH_PROPERTY == 0) { - c = ""; - } else { - // Catenate all result of toString on all elts in list - } - } else { - c = c.toString(); - } - // Replace existing attribute of same name or insert - return; - } - for (i = op->obj.LENGTH - 1; i >= 0; i--) { - // Delete item of same name - } - if (not Found) { - Append new Xml object - - set [[name]], [[class]] == "element" - } - - mprFree(value); -} - - */ -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ - -static int load(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - const char *fileName; - XmlState *parser; - Exml *xp; - MprFile *file; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ep, EJS_ARG_ERROR, "Bad args. Usage: load(fileName);"); - return -1; - } - fileName = argv[0]->string; - - /* MOB -- not romable - Need rom code in MPR not MprServices - */ - file = mprOpen(ep, fileName, O_RDONLY, 0664); - if (file == 0) { - ejsError(ep, EJS_IO_ERROR, "Can't open: %s", fileName); - return -1; - } - - /* MOB -- should we empty thisObj of all existing properties ? */ - - xp = initParser(ep, thisObj, fileName); - parser = exmlGetParseArg(xp); - - exmlSetInputStream(xp, readFileData, (void*) file); - - if (exmlParse(xp) < 0) { - if (! ejsGotException(ep)) { - ejsError(ep, EJS_IO_ERROR, "Can't parse XML file: %s\nDetails %s", - fileName, exmlGetErrorMsg(xp)); - } - termParser(xp); - mprClose(file); - return -1; - } - - ejsSetReturnValue(ep, parser->nodeStack[0].obj); - - termParser(xp); - mprClose(file); - - return 0; -} - -/******************************************************************************/ - -static int loadXmlString(Ejs *ep, EjsVar *thisObj, const char *xmlString) -{ - XmlState *parser; - Exml *xp; - - xp = initParser(ep, thisObj, "string"); - parser = exmlGetParseArg(xp); - - parser->inputBuf = xmlString; - parser->inputSize = strlen(xmlString); - - exmlSetInputStream(xp, readStringData, (void*) 0); - - if (exmlParse(xp) < 0) { - if (! ejsGotException(ep)) { - ejsError(ep, EJS_IO_ERROR, "Can't parse XML string\nError %s", - exmlGetErrorMsg(xp)); - } - termParser(xp); - return -1; - } - - ejsSetReturnValue(ep, parser->nodeStack[0].obj); - - termParser(xp); - - return 0; -} - -/******************************************************************************/ - -static int text(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsVar *vp; - - vp = ejsGetVarPtr(ejsGetSimpleProperty(ep, thisObj, E4X_TEXT_PROPERTY)); - if (vp == 0) { - ejsSetReturnValueToString(ep, ""); - return 0; - } - ejsSetReturnValue(ep, vp); - return 0; -} - -/******************************************************************************/ -/* - * Return the tag name - */ - -static int name(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - EjsVar *vp; - - vp = ejsGetVarPtr(ejsGetSimpleProperty(ep, thisObj, E4X_TAG_NAME_PROPERTY)); - if (vp == 0) { - ejsSetReturnValueToString(ep, ""); - return 0; - } - ejsSetReturnValue(ep, vp); -#if UNDEFINED - char *name; - /* MOB -- not ideal as we can't guarantee thisObj is a property */ - name = ejsGetPropertyPtr(thisObj)->name; - if (name == 0) { - name = ""; - } - ejsSetReturnValueToString(ep, name); -#endif - return 0; -} - -/******************************************************************************/ -/* MOB -- temporary only */ - -static int setText(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1) { - ejsArgError(ep, "usage: setText(string)"); - } - - ejsSetProperty(ep, thisObj, E4X_TEXT_PROPERTY, argv[0]); - ejsSetReturnValue(ep, argv[0]); - return 0; -} - -/******************************************************************************/ - -static Exml *initParser(Ejs *ep, EjsVar *thisObj, const char *fileName) -{ - XmlState *parser; - Exml *xp; - - xp = exmlOpen(ep, 512, E4X_BUF_MAX); - mprAssert(xp); - - /* - * Create the parser stack - */ - parser = mprAllocTypeZeroed(ep, XmlState); - parser->ep = ep; - parser->nodeStack[0].obj = thisObj; - parser->xmlClass = ejsGetClass(ep, 0, "XML"); - parser->xmlListClass = ejsGetClass(ep, 0, "XMLList"); - parser->fileName = fileName; - - exmlSetParseArg(xp, parser); - exmlSetParserHandler(xp, parserHandler); - - return xp; -} - -/******************************************************************************/ - -static void termParser(Exml *xp) -{ - mprFree(exmlGetParseArg(xp)); - exmlClose(xp); -} - -/******************************************************************************/ -/* - * XML parsing callback. Called for each elt and attribute/value pair. - * For speed, we handcraft the object model here rather than calling - * putXmlProperty. - * - * "<!-- txt -->" parseHandler(efd, , EXML_COMMENT); - * "<elt" parseHandler(efd, , EXML_NEW_ELT); - * "...att=value" parseHandler(efd, , EXML_NEW_ATT); - * "<elt ...>" parseHandler(efd, , EXML_ELT_DEFINED); - * "<elt/>" parseHandler(efd, , EXML_SOLO_ELT_DEFINED); - * "<elt> ...<" parseHandler(efd, , EXML_ELT_DATA); - * "...</elt>" parseHandler(efd, , EXML_END_ELT); - * - * Note: we recurse on every new nested elt. - */ - -static int parserHandler(Exml *xp, int state, const char *tagName, - const char *attName, const char *value) -{ - XmlState *parser; - XmlTagState *tos; - EjsVar *currentNode, *vp, *tagNode, *parent, *vpx; - EjsProperty *pp; - Ejs *ep; - char *name; - - parser = (XmlState*) xp->parseArg; - ep = parser->ep; - tos = &parser->nodeStack[parser->topOfStack]; - currentNode = tos->obj; - - mprAssert(state >= 0); - mprAssert(tagName && *tagName); - - switch (state) { - case EXML_PI: - /* - * By using a property name with a leading space, we can store - * non-user-visible processing instructions as regular properties. - */ - pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, E4X_PI_PROPERTY); - ejsMakePropertyEnumerable(pp, 1); - vp = ejsGetVarPtr(pp); - ejsWriteVarAsString(ep, vp, value); - ejsSetVarFlags(vp, EJS_XML_FLAGS_PI); - break; - - case EXML_COMMENT: - /* - * By using a property name with a leading space, we can store - * non- user-visible comments as regular properties. - */ - pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, - E4X_COMMENT_PROPERTY); - ejsMakePropertyEnumerable(pp, 1); - vp = ejsGetVarPtr(pp); - ejsWriteVarAsString(ep, vp, value); - ejsSetVarFlags(vp, EJS_XML_FLAGS_COMMENT); - break; - - case EXML_NEW_ELT: - if (parser->topOfStack > E4X_MAX_NODE_DEPTH) { - ejsError(ep, EJS_IO_ERROR, - "XML nodes nested too deeply in %s at line %d", - parser->fileName, exmlGetLineNumber(xp)); - return MPR_ERR_BAD_SYNTAX; - } - - name = mprStrdup(xp, tagName); - if (name == 0) { - return MPR_ERR_MEMORY; - } - - if (cleanTagName(name) < 0) { - ejsError(ep, EJS_TYPE_ERROR, "Bad XML tag name in %s at %d", - parser->fileName, exmlGetLineNumber(xp)); - mprFree(name); - return MPR_ERR_BAD_SYNTAX; - } - - pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, name); - ejsMakePropertyEnumerable(pp, 1); - - tagNode = ejsGetVarPtr(pp); - - /* MOB -- OPT */ - vpx = ejsCreateXml(ep); - vp = ejsWriteVar(ep, tagNode, vpx, EJS_SHALLOW_COPY); - ejsMakeObjLive(vp, 1); - ejsFreeVar(ep, vpx); - - /* MOB -- return code */ - pp = ejsSetPropertyToString(ep, vp, E4X_TAG_NAME_PROPERTY, name); - ejsMakePropertyEnumerable(pp, 0); - - ejsSetVarFlags(vp, EJS_XML_FLAGS_ELEMENT); - ejsMakePropertyEnumerable(ejsGetPropertyPtr(vp), 1); - - tos = &parser->nodeStack[++(parser->topOfStack)]; - currentNode = tos->obj = vp; - tos->attributes = 0; - tos->comments = 0; - mprFree(name); - break; - - case EXML_NEW_ATT: - if (mprAllocSprintf(MPR_LOC_ARGS(xp), &name, 0, "@%s", attName) < 0) { - return MPR_ERR_MEMORY; - } - pp = ejsCreateProperty(ep, currentNode, name); - ejsMakePropertyEnumerable(pp, 1); - - vp = ejsGetVarPtr(pp); - ejsWriteVarAsString(ep, vp, value); - ejsSetVarFlags(vp, EJS_XML_FLAGS_ATTRIBUTE); - mprFree(name); - break; - - case EXML_SOLO_ELT_DEFINED: - parser->topOfStack--; - mprAssert(parser->topOfStack >= 0); - tos = &parser->nodeStack[parser->topOfStack]; - break; - - case EXML_ELT_DEFINED: - if (parser->topOfStack > 0) { - parent = parser->nodeStack[parser->topOfStack - 1].obj; - ejsSetProperty(ep, currentNode, E4X_PARENT_PROPERTY, parent); - } - break; - - case EXML_ELT_DATA: - case EXML_CDATA: - pp = ejsCreateSimpleNonUniqueProperty(ep, currentNode, - E4X_TEXT_PROPERTY); - ejsMakePropertyEnumerable(pp, 1); - vp = ejsGetVarPtr(pp); - ejsWriteVarAsString(ep, vp, value); - ejsSetVarFlags(vp, EJS_XML_FLAGS_TEXT); - break; - - case EXML_END_ELT: - /* - * This is the closing element in a pair "<x>...</x>". - * Pop the stack frame off the elt stack - */ - parser->topOfStack--; - mprAssert(parser->topOfStack >= 0); - tos = &parser->nodeStack[parser->topOfStack]; - break; - - default: - ejsError(ep, EJS_IO_ERROR, "XML error in %s at %d\nDetails %s", - parser->fileName, exmlGetLineNumber(xp), exmlGetErrorMsg(xp)); - mprAssert(0); - return MPR_ERR_BAD_SYNTAX; - } - return 0; -} - -/******************************************************************************/ - -static char *cleanTagName(char *name) -{ - char *cp; - - for (cp = name; *cp; cp++) { - if (*cp == ':') { - *cp = '_'; - } else if (!isalnum(*cp) && *cp != '_' && *cp != '$' && *cp != '@') { - return 0; - } - } - return name; -} - -/******************************************************************************/ - -static int readFileData(Exml *xp, void *data, char *buf, int size) -{ - mprAssert(xp); - mprAssert(data); - mprAssert(buf); - mprAssert(size > 0); - - return mprRead((MprFile*) data, buf, size); -} - -/******************************************************************************/ - -static int readStringData(Exml *xp, void *data, char *buf, int size) -{ - XmlState *parser; - int rc, len; - - mprAssert(xp); - mprAssert(buf); - mprAssert(size > 0); - - parser = (XmlState*) xp->parseArg; - - if (parser->inputPos < parser->inputSize) { - len = min(size, (parser->inputSize - parser->inputPos)); - rc = mprMemcpy(buf, size, &parser->inputBuf[parser->inputPos], len); - parser->inputPos += len; - return rc; - } - return 0; -} - -/******************************************************************************/ - -static int save(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - const char *fileName; - MprBuf *buf; - MprFile *file; - int bytes, len; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ep, EJS_ARG_ERROR, "Bad args. Usage: save(fileName);"); - return -1; - } - fileName = argv[0]->string; - - /* MOB -- not romable - Need rom code in MPR not MprServices - */ - - /* - * Convert to a string - */ - buf = mprCreateBuf(ep, E4X_BUF_SIZE, E4X_BUF_MAX); - if (xmlToString(ep, buf, thisObj, -1) < 0) { - mprFree(buf); - return -1; - } - - file = mprOpen(ep, fileName, - O_CREAT | O_TRUNC | O_WRONLY | O_TEXT, 0664); - if (file == 0) { - ejsError(ep, EJS_IO_ERROR, "Can't open: %s, %d", fileName, - mprGetOsError()); - return -1; - } - - len = mprGetBufLength(buf); - bytes = mprWrite(file, buf->start, len); - if (bytes != len) { - ejsError(ep, EJS_IO_ERROR, "Can't write to: %s", fileName); - mprClose(file); - return -1; - } - mprWrite(file, "\n", 1); - mprFree(buf); - - mprClose(file); - - return 0; -} - -/******************************************************************************/ - -static int toString(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprBuf *buf; - - buf = mprCreateBuf(ep, E4X_BUF_SIZE, E4X_BUF_MAX); - - if (xmlToString(ep, buf, thisObj, -1) < 0) { - mprFree(buf); - return -1; - } - ejsWriteVarAsString(ep, ep->result, (char*) buf->start); - - mprFree(buf); - - return 0; -} - -/******************************************************************************/ -/* MOB -- need to support XMLList */ - -static int xmlToString(Ejs *ep, MprBuf *buf, EjsVar *obj, int indentLevel) -{ - EjsProperty *pp; - EjsVar *vp; - char *varBuf; - int endTag, sawElements; - - if (indentLevel < 0) { - mprPutStringToBuf(buf, "<?xml version=\"1.0\"?>"); - } - - switch (obj->type) { - case EJS_TYPE_STRING: - if (obj->flags & EJS_XML_FLAGS_ATTRIBUTE) { - mprPutFmtStringToBuf(buf, " %s=\"%s\"", - &ejsGetPropertyPtr(obj)->name[1], obj->string); - /* No new line */ - - } else if (obj->flags & EJS_XML_FLAGS_COMMENT) { - mprPutCharToBuf(buf, '\n'); - indent(buf, indentLevel); - mprPutFmtStringToBuf(buf, "<!-- %s -->", obj->string); - - } else if (obj->flags & EJS_XML_FLAGS_TEXT) { - mprPutStringToBuf(buf, obj->string); - - } else { -// indent(buf, indentLevel); - mprPutStringToBuf(buf, obj->string); -// mprPutCharToBuf(buf, '\n'); - } - break; - - default: - /* Primitive types come here */ - indent(buf, indentLevel); - /* MOB -- rc */ - varBuf = ejsVarToString(ep, obj); - mprPutStringToBuf(buf, varBuf); - break; - - case EJS_TYPE_OBJECT: - if (obj->objectState->baseClass == ejsGetClass(ep, 0, "XML")) { - if (!obj->objectState->visited) { - obj->objectState->visited = 1; - - /* MOB -- opt. Flags would be quicker */ - if (strcmp(ejsGetPropertyPtr(obj)->name, - E4X_PARENT_PROPERTY) == 0) { - return 0; - } - /* - * MOB -- short term fix for tags with no body but with - * attributes - */ - if (getNumElements(obj) == 0 && 0) { - /* - * XML element is simple with no elements, so return just - * the text. - */ - if (getText(buf, obj) < 0) { - ejsError(ep, EJS_IO_ERROR, - "XML is to big to convert to a string"); - obj->objectState->visited = 0; - return -1; - } - - } else if (obj->flags & (EJS_XML_FLAGS_ELEMENT)) { - /* - * XML object is complex (has elements) so return full XML - * content. - */ - mprPutCharToBuf(buf, '\n'); - indent(buf, indentLevel); - - /* - * When called from toString, obj is not a property - */ - if (indentLevel >= 0) { - mprPutFmtStringToBuf(buf, "<%s", - ejsGetPropertyPtr(obj)->name); - endTag = 0; - - } else { - endTag = 1; - } - - sawElements = 0; - pp = ejsGetFirstProperty(obj, 0); - while (pp) { - vp = ejsGetVarPtr(pp); - - if (! (vp->flags & EJS_XML_FLAGS_ATTRIBUTE)) { - if (endTag == 0) { - endTag++; - mprPutStringToBuf(buf, ">"); - } - } - if (vp->flags & EJS_XML_FLAGS_ELEMENT) { - if (strcmp(ejsGetPropertyPtr(vp)->name, - E4X_PARENT_PROPERTY) != 0) { - sawElements++; - } - } - - if (xmlToString(ep, buf, ejsGetVarPtr(pp), - indentLevel + 1) < 0){ - return -1; - } - - pp = ejsGetNextProperty(pp, 0); - } - if (indentLevel >= 0) { - if (sawElements) { - mprPutCharToBuf(buf, '\n'); - indent(buf, indentLevel); - } - mprPutFmtStringToBuf(buf, "</%s>", - ejsGetPropertyPtr(obj)->name); - } - } - obj->objectState->visited = 0; - } - return 0; - } - - if (obj->objectState->baseClass == ejsGetClass(ep, 0, "XMLList")) { - indent(buf, indentLevel); - /* MOB -- TBD */ - return 0; - } - - /* - * All other objects. Allow other objects to override toString - */ - if (ejsRunMethod(ep, obj->objectState->baseClass, "toString", - 0) < 0) { - return -1; - } - if (ejsVarIsString(ep->result)) { - indent(buf, indentLevel); - mprPutStringToBuf(buf, obj->string); - } - break; - } - return 0; -} - -/******************************************************************************/ - -static void indent(MprBuf *bp, int level) -{ - int i; - - for (i = 0; i < level; i++) { - mprPutCharToBuf(bp, '\t'); - } -} - -/******************************************************************************/ - -static int valueOf(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 0) { - mprAssert(0); - return -1; - } - - switch (thisObj->type) { - default: - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - case EJS_TYPE_CMETHOD: - case EJS_TYPE_OBJECT: - case EJS_TYPE_METHOD: - case EJS_TYPE_STRING_CMETHOD: - ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY); - break; - - case EJS_TYPE_STRING: - ejsWriteVarAsInteger(ep, ep->result, atoi(thisObj->string)); - break; - - case EJS_TYPE_BOOL: - case EJS_TYPE_INT: -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: -#endif -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: -#endif - ejsWriteVar(ep, ep->result, thisObj, EJS_SHALLOW_COPY); - break; - } - return 0; -} - -/******************************************************************************/ - -static int getList(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - const char *nodeName; - EjsProperty *pp; - EjsVar *list, *vp; - - if (argc != 1) { - nodeName = 0; - } else { - nodeName = argv[0]->string; - } - - list = ejsCreateArray(ep, 0); - - pp = ejsGetFirstProperty(thisObj, EJS_ENUM_ALL); - while (pp) { - vp = ejsGetVarPtr(pp); - if (vp->type == EJS_TYPE_OBJECT) { - if (strcmp(ejsGetPropertyPtr(vp)->name, E4X_PARENT_PROPERTY) != 0) { - if (vp->flags & EJS_XML_FLAGS_ELEMENT && - (nodeName == 0 || strcmp(nodeName, pp->name) == 0)) { - ejsAddArrayElt(ep, list, vp, EJS_SHALLOW_COPY); - } - } - } - pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); - } - - ejsSetReturnValueAndFree(ep, list); - return 0; -} - -/******************************************************************************/ - -static int getNumElements(EjsVar *obj) -{ - EjsProperty *pp; - int count; - - count = 0; - pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL); - while (pp) { - if (ejsGetVarPtr(pp)->flags & EJS_XML_FLAGS_ELEMENT) { - count++; - } - pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); - } - return count; -} - -/******************************************************************************/ -/* MOB - This needs to be a public method */ - -static int getText(MprBuf *buf, EjsVar *obj) -{ - EjsProperty *pp; - EjsVar *vp; - - pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL); - while (pp) { - vp = ejsGetVarPtr(pp); - if (vp->flags & EJS_XML_FLAGS_TEXT) { - /* MOB -- should test for overflow */ - mprPutStringToBuf(buf, vp->string); - } - pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); - } - return 0; -} - -/******************************************************************************/ -/******************************************************************************/ -/******************************** Internal Methods ****************************/ -/******************************************************************************/ - -static EjsVar *createXmlListProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - return ejsGetVarPtr(ejsCreateProperty(ep, obj, property)); -} - -/******************************************************************************/ - -static int deleteXmlListProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - return ejsDeleteProperty(ep, obj, property); -} - -/******************************************************************************/ - -static EjsVar *getXmlListProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - // Must always return XML or XMLList event for comments and attributes - return ejsGetVarPtr(ejsGetSimpleProperty(ep, obj, property)); -} - -/******************************************************************************/ - -static EjsVar *setXmlListProperty(Ejs *ep, EjsVar *obj, const char *property, - const EjsVar *value) -{ - EjsProperty *pp; - EjsVar *vp; - - pp = ejsGetSimpleProperty(ep, obj, property); - if (pp == 0) { - mprAssert(pp); - return 0; - } - vp = ejsGetVarPtr(pp); - if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) < 0){ - mprAssert(0); - return 0; - } - return ejsGetVarPtr(pp); -} - -/******************************************************************************/ -/* - NEW - -static EjsVar *putXmlListProperty(EjsVar *op, const char *property, - EjsVar *value) -{ - - if ((value->objectState->baseClass != XML && - value->objectState->baseClass != XMLList) || - value->string[0] != '<') { - c = value.toString(); - } else { - value = ejsDupVar(value); - ?? - } - if (isdigit(*property)) { - // ERROR - return 0; - } - if (*property == '@') { - if (op->objectState->baseClass == XMLList) { - if (op->obj.LENGTH_PROPERTY == 0) { - c = ""; - } else { - // Catenate all result of toString on all elts in list - } - } else { - c = c.toString(); - } - // Replace existing attribute of same name or insert - return; - } - for (i = op->obj.LENGTH - 1; i >= 0; i--) { - // Delete item of same name - } - if (not Found) { - Append new Xml object - - set [[name]], [[class]] == "element" - } -} - - */ - -/******************************************************************************/ -#else -void ejs4xDummy() {} - -/******************************************************************************/ -#endif /* BLD_FEATURE_EJS_E4X */ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejs.c b/source4/lib/appweb/ejs-2.0/ejs/ejs.c deleted file mode 100644 index 0fcc6f0545..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejs.c +++ /dev/null @@ -1,1378 +0,0 @@ -/* - * @file ejs.c - * @brief Embedded JavaScript (EJS) - * @overview Main module interface logic. - * @remarks The initialization code must be run single-threaded. Includes: - * ejsOpen, ejsClose. - */ -/********************************* Copyright **********************************/ -/* - * @copy default - * - * Copyright (c) Mbedthis Software LLC, 2003-2006. 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 ***********************************/ -/* - * Initialize the EJS subsystem - */ - -EjsService *ejsOpenService(MprCtx ctx) -{ - EjsService *service; - Ejs *interp; - - service = mprAllocTypeZeroed(ctx, EjsService); - if (service == 0) { - mprError(ctx, MPR_LOC, "Can't allocate service memory"); - return 0; - } - - interp = ejsCreateInterp(service, 0, 0, 0, 1); - if (interp == 0) { - mprError(ctx, MPR_LOC, "Can't create master interpreter"); - mprFree(service); - return 0; - } - service->master = interp; - - /* - * Restore the default GC settings for the master interpreter. - * ejsCreateInterp will have initialized them. - */ - ejsGCInit(interp, EJS_DEFAULT_OBJ_INC, EJS_DEFAULT_PROP_INC, - EJS_DEFAULT_VAR_INC, EJS_DEFAULT_STR_INC); - - /* - * Save the default interpreter and global class for all to access - * MOB -- don't store these. Store the service - */ - mprSetKeyValue(interp, "ejsMaster", interp); - mprSetKeyValue(interp, "ejsGlobalClass", interp->global); - - /* - * Once the Object class is created, this routine will also make the - * Global class a subclass of Object. - */ - if (ejsDefineObjectClass(interp) < 0) { - mprError(ctx, MPR_LOC, "Can't define EJS object class"); - mprFree(service); - return 0; - } - - /* - * Create all the standard classes - */ - if (ejsDefineStandardClasses(interp) < 0) { - mprError(ctx, MPR_LOC, "Can't define EJS standard classes"); - mprFree(service); - return 0; - } - - if (ejsDefineSystemClasses(interp) < 0) { - mprError(ctx, MPR_LOC, "Can't define EJS system classes"); - mprFree(service); - return 0; - } - - if (ejsCreateObjectModel(interp) < 0) { - mprError(ctx, MPR_LOC, "Can't create EJS object model"); - mprFree(service); - return 0; - } - -#if UNUSED && BLD_FEATURE_ALLOC_STATS -{ - EjsVar v; - mprLog(ctx, 0, "Obj %d, Var %d, Prop %d\n", sizeof(EjsObj), sizeof(EjsVar), - sizeof(EjsProperty)); - mprLog(ctx, 0, "GCLink %d\n", sizeof(EjsGCLink)); - mprLog(ctx, 0, "objectState %d\n", (uint) &v.objectState - (uint) &v); -} -#endif - - return service; -} - -/******************************************************************************/ -/* - * Close down the EJS Service - */ - -void ejsCloseService(EjsService *sp, bool doStats) -{ - Ejs *ep; - - mprAssert(sp); - - ep = sp->master; - mprAssert(ep); - - ejsTermSystemClasses(ep); - - if (ep) { - ejsFreeVar(ep, sp->globalClass); - -#if BLD_FEATURE_ALLOC_STATS - if (doStats) { - mprLog(sp, 0, "GC Statistics for the Global Interpreter"); - } -#endif - ejsDestroyInterp(ep, doStats); - } - - mprRemoveKeyValue(sp, "ejsMaster"); - mprRemoveKeyValue(sp, "ejsGlobalClass"); - - mprFree(sp); -} - -/******************************************************************************/ - -Ejs *ejsGetMasterInterp(EjsService *sp) -{ - return sp->master; -} - -/******************************************************************************/ -#if BLD_FEATURE_MULTITHREAD - -int ejsSetServiceLocks(EjsService *sp, EjsLockFn lock, EjsUnlockFn unlock, - void *data) -{ - mprAssert(sp); - - sp->lock = lock; - sp->unlock = unlock; - sp->lockData = data; - return 0; -} - -#endif -/******************************************************************************/ -/* - * Create and initialize an EJS interpreter. Interpreters have a global object - * that has the service global class set as a base class. This way, it - * inherits all the desired global properties, methods and classes. - * - * The primary and alternate handles are provided to C methods depending on - * the flags provided when the C methods are defined. The global variable - * (optionally) defines a predefined global variable space. - */ - -Ejs *ejsCreateInterp(EjsService *sp, void *primaryHandle, void *altHandle, - EjsVar *global, bool useOwnSlab) -{ - EjsProperty *pp; - EjsVar *baseClass; - Ejs *ep; - - ep = mprAllocTypeZeroed(sp, Ejs); - if (ep == 0) { - mprAssert(0); - return ep; - } - - ep->stkPtr = &ep->stack[EJS_MAX_STACK]; - - ep->service = sp; - ep->primaryHandle = primaryHandle; - ep->altHandle = altHandle; - - if (sp->master) { - ep->objectClass = sp->master->objectClass; - } - - if (useOwnSlab) { - ep->slabs = (EjsSlab*) mprAllocZeroed(ep, sizeof(EjsSlab) * - EJS_SLAB_MAX); - ep->slabAllocContext = ep; - - } else { - ep->slabs = sp->master->slabs; - ep->slabAllocContext = sp->master; - ep->flags |= EJS_FLAGS_SHARED_SLAB; - } - - ep->frames = mprCreateItemArray(ep, EJS_INC_FRAMES, EJS_MAX_FRAMES); - if (ep->frames == 0) { - mprFree(ep); - return 0; - } - - ejsGCInit(ep, EJS_OBJ_INC, EJS_PROP_INC, EJS_VAR_INC, EJS_STR_INC); - - if (sp->globalClass == 0) { - /* - * Only do this for the Global interpreter. Create a global class - * (prototype) object. This is base class from which all global - * spaces will inherit. - */ - sp->globalClass = ejsCreateObjVar(ep); - if (sp->globalClass == 0) { - mprFree(ep); - return 0; - } - ejsSetClassName(ep, sp->globalClass, "Global"); - global = sp->globalClass; - } - - if (global) { - /* - * The default interpreter uses the Global class as its global - * space. - */ - ep->global = ejsDupVar(ep, global, EJS_SHALLOW_COPY); - if (ep->global == 0) { - mprFree(ep); - return 0; - } - if (ep->global->objectState != sp->globalClass->objectState) { - ejsSetBaseClass(ep->global, sp->globalClass); - } - - } else { - /* - * Use the global class as our global so we can find the object class - */ - baseClass = ejsGetClass(ep, sp->globalClass, "Object"); - if (baseClass) { - ep->global = ejsCreateSimpleObjUsingClass(ep, baseClass); - if (ep->global == 0) { - mprFree(ep); - return 0; - } - - /* - * Override the base class and set to the master Global class - */ - ejsSetBaseClass(ep->global, sp->globalClass); - - } else { - ep->global = ejsCreateObjVar(ep); - } - } - - /* - * The "global" variable points to the global space - */ - pp = ejsSetProperty(ep, ep->global, "global", ep->global); - if (pp == 0) { - mprFree(ep); - return 0; - } - ejsMakePropertyEnumerable(pp, 0); - - /* - * The "Global" variable points to the Global class - */ - pp = ejsSetProperty(ep, ep->global, "Global", sp->globalClass); - if (pp == 0) { - mprFree(ep); - return 0; - } - ejsMakePropertyEnumerable(pp, 0); - - ep->local = ejsDupVar(ep, ep->global, EJS_SHALLOW_COPY); - if (ep->frames == 0 || ep->global == 0 || ep->local == 0) { - mprFree(ep); - return 0; - } - ejsSetVarName(ep, ep->local, "topLevelLocal"); - - if (mprAddItem(ep->frames, ep->global) < 0 || - mprAddItem(ep->frames, ep->local) < 0) { - mprFree(ep); - return 0; - } - - ep->result = ejsCreateUndefinedVar(ep); - if (ep->result == 0) { - mprFree(ep); - return 0; - } - - return ep; -} - -/******************************************************************************/ -/* - * Close an EJS interpreter - */ - -void ejsDestroyInterp(Ejs *ep, bool doStats) -{ - ejsCleanInterp(ep, doStats); - - mprFree(ep); -} - -/******************************************************************************/ -/* - * Clean an EJS interpreter of all allocated variables, but DONT destroy. - * We use this rather than DestroyInterp so we delay freeing the Ejs struct - * until after the service is closed. - */ - -void ejsCleanInterp(Ejs *ep, bool doStats) -{ - int i; - - if (ep->global) { - ejsDeleteProperty(ep, ep->local, "global"); - ejsDeleteProperty(ep, ep->global, "global"); - ep->global = 0; - } - if (ep->local) { - ejsFreeVar(ep, ep->local); - ep->local = 0; - } - if (ep->global) { - ejsFreeVar(ep, ep->global); - ep->global = 0; - } - if (ep->result) { - ejsFreeVar(ep, ep->result); - ep->result = 0; - } - if (ep->castAlloc && ep->castTemp) { - mprFree(ep->castTemp); - ep->castTemp = 0; - } - if (ep->frames) { - for (i = ep->frames->length - 1; i >= 0; i--) { - mprRemoveItemByIndex(ep->frames, i); - } - mprFree(ep->frames); - ep->frames = 0; - } - - if (doStats) { - -#if BLD_FEATURE_ALLOC_STATS - mprLog(ep, 0, " "); - mprLog(ep, 0, "GC Statistics for Interpreter (0x%X)", (uint) ep); -#endif - - /* - * Cleanup before printing the alloc report - */ - ejsSetGCDebugLevel(ep, 3); - ejsCollectGarbage(ep, -1); - -#if BLD_DEBUG - /* - * If we are the master, dump objects - */ - if (ep->service->master == ep) { - ejsDumpObjects(ep); - } -#endif - -#if BLD_FEATURE_ALLOC_STATS - /* - * Print an alloc report. 1 == do leak report - */ - ejsPrintAllocReport(ep, 1); -#endif - - } else { - /* - * Must collect garbage here incase sharing interpreters with the - * master. If we don't, the mprFree later in DestroyInterp will free - * all memory and when the master does GC --> crash. - */ - ejsCollectGarbage(ep, -1); - } -} - -/******************************************************************************/ -/* - * Evaluate an EJS script file. This will evaluate the script at the current - * context. Ie. if inside a function, declarations will be local. - */ - -int ejsEvalFile(Ejs *ep, const char *path, EjsVar *result) -{ - MprFile *file; - MprFileInfo info; - char *script; - char *saveFileName; - int rc; - - mprAssert(path && *path); - - if ((file = mprOpen(ep, path, O_RDONLY | O_BINARY, 0666)) == 0) { - ejsError(ep, EJS_IO_ERROR, "Can't open %s", path); - return -1; - } - - if (mprGetFileInfo(ep, path, &info) < 0) { - ejsError(ep, EJS_IO_ERROR, "Can't get file info for %s", path); - goto error; - } - - if ((script = (char*) mprAlloc(ep, info.size + 1)) == NULL) { - ejsError(ep, "MemoryError", "Cant malloc %d", (int) info.size); - goto error; - } - - if (mprRead(file, script, info.size) != (int) info.size) { - mprFree(script); - ejsError(ep, EJS_IO_ERROR, "Error reading %s", path); - goto error; - } - mprClose(file); - script[info.size] = '\0'; - - saveFileName = ep->fileName; - ep->fileName = mprStrdup(ep, path); - - rc = ejsEvalScript(ep, script, result); - mprFree(script); - - mprFree(ep->fileName); - ep->fileName = saveFileName; - - return rc; - -/* - * Error return - */ -error: - mprClose(file); - return -1; -} - -/******************************************************************************/ -/* - * Create a new variable scope block. This pushes the old local frame down - * the stack and creates a new local variables frame. - */ - -int ejsOpenBlock(Ejs *ep) -{ - EjsProperty *pp; - int fid; - - ep->local = ejsCreateSimpleObj(ep, "Object"); - ejsSetVarName(ep, ep->local, "local"); - - if (ep->local == 0) { - ejsMemoryError(ep); - return -1; - } - - if (ep->frames->length > EJS_MAX_FRAMES && !ep->gotException) { - ejsError(ep, EJS_RANGE_ERROR, "Recursion too deep: Max depth %d", - EJS_MAX_FRAMES); - return -1; - } - - /* - * Must add to frames before ejsSetProperty which will make the object live - */ - fid = mprAddItem(ep->frames, ep->local); - if (fid < 0) { - ejsMemoryError(ep); - return -1; - } - - /* Self reference */ - pp = ejsSetProperty(ep, ep->local, "local", ep->local); - ejsMakePropertyEnumerable(pp, 0); - - return fid; -} - -/******************************************************************************/ -/* - * Set a new variable scope block. This pushes the old local frame down - * the stack and creates a new local variables frame. - */ - -int ejsSetBlock(Ejs *ep, EjsVar *local) -{ - ep->local = ejsDupVar(ep, local, EJS_SHALLOW_COPY); - ejsMakeObjPermanent(ep->local, 1); - return mprAddItem(ep->frames, ep->local); -} - -/******************************************************************************/ -/* - * Close a variable scope block opened via ejsOpenBlock. Pop back the old - * local variables frame. - */ - -int ejsCloseBlock(Ejs *ep, int fid) -{ - mprAssert(ep->local >= 0); - mprAssert(fid >= 0); - - mprAssert(ep->local == (EjsVar*) mprGetItem(ep->frames, fid)); - - if (ep->local) { - /* Allow GC */ - ejsMakeObjPermanent(ep->local, 0); - ejsFreeVar(ep, ep->local); - } - - mprRemoveItemByIndex(ep->frames, fid); - - ep->local = (EjsVar*) mprGetItem(ep->frames, - mprGetItemCount(ep->frames) - 1); - - return 0; -} - -/******************************************************************************/ -/* - * Create a new variable scope block and evaluate a script. All frames - * created during this context will be automatically deleted when complete. - * vp is optional. i.e. created local variables will be discarded - * when this routine returns. - */ - -int ejsEvalBlock(Ejs *ep, char *script, EjsVar *vp) -{ - int rc, fid; - - mprAssert(script); - - fid = ejsOpenBlock(ep); - if (fid < 0) { - return fid; - } - - rc = ejsEvalScript(ep, script, vp); - - ejsCloseBlock(ep, fid); - - return rc; -} - -/******************************************************************************/ -/* - * Parse and evaluate a EJS. The script is evaluated at the current context. - * Return the result in *vp. The result is "owned" by EJ and the caller - * must not free it. Returns -1 on errors and zero for success. - */ - -int ejsEvalScript(Ejs *ep, const char *script, EjsVar *vp) -{ - int state; - - ejsClearVar(ep, ep->result); - ep->gotException = 0; - - if (script == 0) { - return 0; - } - - /* - * Allocate a new evaluation block, and save the old one - */ - if (ejsLexOpenScript(ep, script) < 0) { - return MPR_ERR_MEMORY; - } - - /* - * Do the actual parsing and evaluation - */ - ep->scriptStatus = 0; - - do { - state = ejsParse(ep, EJS_STATE_BEGIN, EJS_FLAGS_EXE); - - if (state == EJS_STATE_RET) { - state = EJS_STATE_EOF; - } - } while (state != EJS_STATE_EOF && state != EJS_STATE_ERR); - - ejsLexCloseScript(ep); - - if (state == EJS_STATE_ERR) { - return -1; - } - - if (vp) { - /* Caller must not free. */ - *vp = *ep->result; - } - - return ep->scriptStatus; -} - -/******************************************************************************/ - -void ejsSetFileName(Ejs *ep, const char *fileName) -{ - mprFree(ep->fileName); - ep->fileName = mprStrdup(ep, fileName); -} - -/******************************************************************************/ -/* - * Format the stack backtrace - */ - -char *ejsFormatStack(Ejs* ep) -{ - EjsInput *ip; - char *errbuf; - int frame, len; - - mprAssert(ep); - - ip = ep->input; - - errbuf = 0; - - len = 0; - frame = 0; - while (ip && frame < EJS_MAX_BACKTRACE) { - char *traceLine, *newErrbuf, *line; - for (line = ip->line; *line && isspace(*line); line++) { - ; - } - mprAllocSprintf(MPR_LOC_ARGS(ep), &traceLine, MPR_MAX_STRING, - " [%02d] %s, %s, line %d -> %s\n", - frame++, - ip->fileName ? ip->fileName : "script", - ip->procName ? ip->procName: "global", - ip->lineNumber, line); - if (traceLine == 0) { - break; - } - newErrbuf = mprRealloc(ep, errbuf, len + strlen(traceLine) + 1); - if (newErrbuf == NULL) { - break; - } - errbuf = newErrbuf; - memcpy(&errbuf[len], traceLine, strlen(traceLine) + 1); - len += strlen(traceLine); - mprFree(traceLine); - ip = ip->next; - } - return errbuf; -} - -/******************************************************************************/ -/* - * Internal use method to set the error message - * - * Error, ArgError, AssertError, IOError, MemoryError, RangeError, - * ReferenceError, SyntaxError, TypeError, MemoryError - */ - -void ejsError(Ejs* ep, const char *errorType, const char* fmt, ...) -{ - va_list fmtArgs; - EjsVar *error; - char *msg, *stack; - - va_start(fmtArgs, fmt); - mprAllocVsprintf(MPR_LOC_ARGS(ep), &msg, MPR_MAX_STRING, fmt, fmtArgs); - va_end(fmtArgs); - - /* - * Create a new Error exception object. If bad error type, default to - * "Error" - */ - if (ejsGetClass(ep, 0, errorType) == 0) { - errorType = "Error"; - } - ep->gotException = 1; - - error = ejsCreateObj(ep, 0, errorType, msg); - if (error == 0) { - return; - } - mprFree(msg); - - stack = ejsFormatStack(ep); - ejsSetPropertyToString(ep, error, "stack", stack); - mprFree(stack); - - ejsWriteVar(ep, ep->result, error, EJS_SHALLOW_COPY); - ejsFreeVar(ep, error); -} - -/******************************************************************************/ - -void ejsSyntaxError(Ejs *ep, const char *msg) -{ - if (msg == 0) { - msg = " "; - } - ejsError(ep, EJS_SYNTAX_ERROR, msg); -} - -/******************************************************************************/ - -void ejsMemoryError(Ejs *ep) -{ - ejsError(ep, EJS_MEMORY_ERROR, "Memory allocation error"); -} - -/******************************************************************************/ - -void ejsArgError(Ejs *ep, const char *msg) -{ - mprAssert(msg && *msg); - - ejsError(ep, EJS_ARG_ERROR, msg); -} - -/******************************************************************************/ - -void ejsInternalError(Ejs *ep, const char *msg) -{ - mprAssert(msg && *msg); - - ejsError(ep, EJS_INTERNAL_ERROR, msg); -} - -/******************************************************************************/ -/* - * Public routine to set the error message. Caller MUST NOT free. - */ - -char *ejsGetErrorMsg(Ejs *ep) -{ - EjsVar *error; - const char *message, *stack, *name; - char *buf; - - error = ep->result; - - if (! ejsVarIsObject(error)) { - name = message = stack = 0; - } else { - name = ejsGetPropertyAsString(ep, error, "name"); - message = ejsGetPropertyAsString(ep, error, "message"); - stack = ejsGetPropertyAsString(ep, error, "stack"); - } - if (name == 0 || message == 0) { - buf = mprStrdup(ep, "Unspecified execution error\n"); - } else { - mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, - "%s Exception: %s\nStack:\n%s\n", - name, message, stack ? stack : " " ); - } - mprFree(ep->errorMsg); - ep->errorMsg = buf; - return buf; -} - -/******************************************************************************/ -/* - * Get the current line number - */ - -int ejsGetLineNumber(Ejs *ep) -{ - if (ep->input == 0) { - return -1; - } - return ep->input->lineNumber; -} - -/******************************************************************************/ -/* - * Return the local object - */ - -EjsVar *ejsGetLocalObj(Ejs *ep) -{ - return ep->local; -} - -/******************************************************************************/ -/* - * Return the global object - */ - -EjsVar *ejsGetGlobalObj(Ejs *ep) -{ - return ep->global; -} - -/******************************************************************************/ -/* - * Set the expression return value - */ - -void ejsSetReturnValue(Ejs *ep, EjsVar *vp) -{ - mprAssert(ep); - mprAssert(vp); - - if (vp == 0) { - return; - } - ejsWriteVar(ep, ep->result, vp, EJS_SHALLOW_COPY); -} - -/******************************************************************************/ -/* - * Set the expression return value and free the arg. - */ - -void ejsSetReturnValueAndFree(Ejs *ep, EjsVar *vp) -{ - mprAssert(ep); - mprAssert(vp); - - ejsWriteVar(ep, ep->result, vp, EJS_SHALLOW_COPY); - ejsFreeVar(ep, vp); -} - -/******************************************************************************/ -/* - * Set the expression return value to a string value. - */ - -void ejsSetReturnValueToString(Ejs *ep, const char *value) -{ - mprAssert(ep); - mprAssert(value); - - ejsWriteVarAsString(ep, ep->result, value); -} - -/******************************************************************************/ -/* - * Set the expression return value to a binary string value. - */ - -void ejsSetReturnValueToBinaryString(Ejs *ep, const uchar *value, int len) -{ - mprAssert(ep); - mprAssert(value); - - ejsWriteVarAsBinaryString(ep, ep->result, value, len); -} - -/******************************************************************************/ -/* - * Set the expression return value to a integer value. - */ - -void ejsSetReturnValueToInteger(Ejs *ep, int value) -{ - mprAssert(ep); - - ejsWriteVarAsInteger(ep, ep->result, value); -} - -/******************************************************************************/ -/* - * Set the expression return value to an EjsNum value. - */ - -void ejsSetReturnValueToNumber(Ejs *ep, EjsNum value) -{ - mprAssert(ep); - - ejsWriteVarAsNumber(ep, ep->result, value); -} - -/******************************************************************************/ -/* - * Set the expression return value to a boolean value. - */ - -void ejsSetReturnValueToBoolean(Ejs *ep, int value) -{ - mprAssert(ep); - - ejsWriteVarAsBoolean(ep, ep->result, value); -} - -/******************************************************************************/ -/* - * Set the expression return value to a boolean value. - */ - -void ejsSetReturnValueToUndefined(Ejs *ep) -{ - mprAssert(ep); - - ejsWriteVarAsUndefined(ep, ep->result); -} - -/******************************************************************************/ -/* - * Get the expression return value - */ - -EjsVar *ejsGetReturnValue(Ejs *ep) -{ - mprAssert(ep); - - return ep->result; -} - -/******************************************************************************/ - -void *ejsGetUserData(Ejs *ep) -{ - mprAssert(ep); - - return ep->userData; -} - -/******************************************************************************/ -/* - * Get a variable given a full variable spec possibly containing "." or "[]". - */ - -EjsVar *ejsGetVar(Ejs *ep, const char *fullName) -{ - mprAssert(ep); - mprAssert(fullName && *fullName); - - return ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 0); -} - -/******************************************************************************/ -/* - * Get a string var given a full variable spec possibly containing "." or "[]". - */ - -const char *ejsGetStr(Ejs *ep, const char *fullName, const char *defaultValue) -{ - EjsVar *vp; - - mprAssert(fullName && *fullName); - - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 0); - if (vp == 0 || !ejsVarIsString(vp)) { - return defaultValue; - } - /* MOB -- what about VarToStr */ - return vp->string; -} - -/******************************************************************************/ -/* - * Get an int var given a full variable spec possibly containing "." or "[]". - */ - -int ejsGetInt(Ejs *ep, const char *fullName, int defaultValue) -{ - EjsVar *vp; - - mprAssert(ep); - mprAssert(fullName && *fullName); - - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 0); - if (vp == 0 || !ejsVarIsInteger(vp)) { - return defaultValue; - } - /* MOB -- should use VarToInt */ - return vp->integer; -} - -/******************************************************************************/ -/* - * Get an bool var given a full variable spec possibly containing "." or "[]". - */ - -int ejsGetBool(Ejs *ep, const char *fullName, int defaultValue) -{ - EjsVar *vp; - - mprAssert(ep); - mprAssert(fullName && *fullName); - - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 0); - if (vp == 0 || !ejsVarIsBoolean(vp)) { - return defaultValue; - } - /* MOB -- should use VarToBool */ - return vp->boolean; -} - -/******************************************************************************/ -/* - * Set a variable that may be an arbitrarily complex object or array reference. - * Will always define in the top most variable frame. - */ - -int ejsSetVar(Ejs *ep, const char *fullName, const EjsVar *value) -{ - EjsVar *vp; - - mprAssert(fullName && *fullName); - - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1); - if (vp == 0) { - return MPR_ERR_CANT_CREATE; - } - - if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) == 0) { - return MPR_ERR_CANT_WRITE; - } - - return 0; -} - -/******************************************************************************/ -/* - * Set a variable that may be an arbitrarily complex object or array reference. - * Will always define in the top most variable frame. - */ - -int ejsSetStr(Ejs *ep, const char *fullName, const char *value) -{ - EjsVar *vp; - - mprAssert(fullName && *fullName); - - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1); - if (vp == 0) { - return MPR_ERR_CANT_CREATE; - } - - if (ejsWriteVarAsString(ep, vp, value) == 0) { - return MPR_ERR_CANT_WRITE; - } - - return 0; -} - -/******************************************************************************/ -/* - * Set a variable that may be an arbitrarily complex object or array reference. - * Will always define in the top most variable frame. - */ - -int ejsSetInt(Ejs *ep, const char *fullName, int value) -{ - EjsVar *vp; - - mprAssert(fullName && *fullName); - - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1); - if (vp == 0) { - return MPR_ERR_CANT_CREATE; - } - - /* Can't fail */ - ejsWriteVarAsInteger(ep, vp, value); - - return 0; -} - -/******************************************************************************/ -/* - * Set a variable that may be an arbitrarily complex object or array reference. - * Will always define in the top most variable frame. - */ - -int ejsSetBool(Ejs *ep, const char *fullName, bool value) -{ - EjsVar *vp; - - mprAssert(fullName && *fullName); - - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1); - if (vp == 0) { - return MPR_ERR_CANT_CREATE; - } - - /* Can't fail */ - ejsWriteVarAsBoolean(ep, vp, value); - - return 0; -} - -/******************************************************************************/ -/* - * Set a variable that may be an arbitrarily complex object or array reference. - * Will always define in the top most variable frame. Free the value passed in. - */ - -int ejsSetVarAndFree(Ejs *ep, const char *fullName, EjsVar *value) -{ - EjsVar *vp; - - mprAssert(fullName && *fullName); - - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, fullName, 1); - if (vp == 0) { - return MPR_ERR_CANT_CREATE; - } - - if (ejsWriteVar(ep, vp, value, EJS_SHALLOW_COPY) == 0) { - ejsFreeVar(ep, value); - return MPR_ERR_CANT_WRITE; - } - - ejsFreeVar(ep, value); - return 0; -} - -/******************************************************************************/ -/* - * Delete a variable - */ - -int ejsDeleteVar(Ejs *ep, const char *fullName) -{ - EjsVar *vp; - EjsVar *obj; - char *propertyName; - - vp = ejsFindProperty(ep, &obj, &propertyName, ep->global, ep->local, - fullName, 0); - if (vp == 0) { - return -1; - } - - mprAssert(propertyName); - mprAssert(propertyName); - - return ejsDeleteProperty(ep, obj, propertyName); -} - -/******************************************************************************/ -/* - * Utility routine to crack JavaScript arguments. Return the number of args - * seen. This routine only supports %s and %d type args. - * - * Typical usage: - * - * if (ejsParseArgs(argc, argv, "%s %d", &name, &age) < 2) { - * // Insufficient args - * return -1; - * } - */ - -int ejsParseArgs(int argc, char **argv, const char *fmt, ...) -{ - va_list vargs; - const char *cp; - char **sp, *s; - int *bp, *ip, argn; - - va_start(vargs, fmt); - - if (argv == 0) { - return 0; - } - - for (argn = 0, cp = fmt; cp && *cp && argn < argc && argv[argn]; ) { - if (*cp++ != '%') { - continue; - } - - s = argv[argn]; - switch (*cp) { - case 'b': - bp = va_arg(vargs, int*); - if (bp) { - if (strcmp(s, "true") == 0 || s[0] == '1') { - *bp = 1; - } else { - *bp = 0; - } - } else { - *bp = 0; - } - break; - - case 'd': - ip = va_arg(vargs, int*); - *ip = atoi(s); - break; - - case 's': - sp = va_arg(vargs, char**); - *sp = s; - break; - - default: - mprAssert(0); - } - argn++; - } - - va_end(vargs); - return argn; -} - -/******************************************************************************/ -/* - * Define the standard classes - */ - -int ejsDefineStandardClasses(Ejs *master) -{ - if (ejsDefineArrayClass(master) != 0 || - ejsDefineBooleanClass(master) != 0 || - ejsDefineErrorClasses(master) != 0 || - ejsDefineFunctionClass(master) != 0 || - ejsDefineNumberClass(master) != 0 || -#if FUTURE - ejsDefineDateClass(master) != 0 || -#endif -#if BLD_FEATURE_EJS_E4X - ejsDefineXmlClasses(master) != 0 || -#endif -#if BLD_FEATURE_EJS_DB && NOT_HERE - ejsDefineDbClasses(master) != 0 || -#endif - ejsDefineStringClass(master) != 0) { - return MPR_ERR_MEMORY; - } - return 0; -} - -/******************************************************************************/ -/* - * Define the EJS System Object Model - */ - -int ejsDefineSystemClasses(Ejs *master) -{ - if (ejsDefineSystemClass(master) != 0 || - ejsDefineAppClass(master) != 0 || - ejsDefineMemoryClass(master) != 0 || - ejsDefineLogClass(master) != 0 || - ejsDefineDebugClass(master) != 0 || - ejsDefineGCClass(master) != 0 || - ejsDefineFileSystemClass(master) != 0 || -#if BREW - ejsDefineFileClass(master) != 0 || - ejsDefineHTTPClass(master) != 0 || -#endif - ejsDefineGlobalProperties(master) != 0) { - return MPR_ERR_MEMORY; - } - return 0; -} - -/******************************************************************************/ -/* - * Terminate the system object model and classes - */ - -int ejsTermSystemClasses(Ejs *master) -{ -#if BREW - ejsTermHTTPClass(master); -#endif - return 0; -} - -/******************************************************************************/ -/* - * Define the EJS object model - */ - -int ejsCreateObjectModel(Ejs *ejs) -{ - EjsProperty *pp; - - pp = ejsSetPropertyToNewObj(ejs, ejs->global, "system", "System", 0); - if (pp == 0) { - return MPR_ERR_MEMORY; - } - - if (ejsSetPropertyToNewObj(ejs, ejsGetVarPtr(pp), "app", "System.App", - 0) == 0) { - return MPR_ERR_MEMORY; - } - return 0; -} - -/******************************************************************************/ - -void ejsTrace(Ejs *ep, const char *fmt, ...) -{ - va_list args; - char buf[MPR_MAX_LOG_STRING]; - int len; - - va_start(args, fmt); - len = mprVsprintf(buf, sizeof(buf) - 1, fmt, args); - va_end(args); - - mprLog(ep, 0, buf, len); - - va_end(args); -} - -/******************************************************************************/ - -bool ejsGotException(Ejs *ep) -{ - return (bool) ep->gotException; -} - -/******************************************************************************/ - -void ejsSetPrimaryHandle(Ejs *ep, void *primaryHandle) -{ - mprAssert(ep); - - ep->primaryHandle = primaryHandle; -} - -/******************************************************************************/ - -void ejsSetAlternateHandle(Ejs *ep, void *alternateHandle) -{ - mprAssert(ep); - - ep->altHandle = alternateHandle; -} - -/******************************************************************************/ - -#else -void ejsDummy() {} - -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejs.h b/source4/lib/appweb/ejs-2.0/ejs/ejs.h deleted file mode 100644 index a926446524..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejs.h +++ /dev/null @@ -1,849 +0,0 @@ -/* - * ejs.h - EJScript Language (ECMAScript) header. - */ - -/********************************* Copyright **********************************/ -/* - * @copy default.g - * - * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. - * Copyright (c) Michael O'Brien, 1994-1995. 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 **********************************/ - -#ifndef _h_EJS -#define _h_EJS 1 - -#include "mpr.h" -#include "ejsVar.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/********************************* Prototypes *********************************/ -/* - * Constants - */ -#if BLD_FEATURE_SQUEEZE - #define EJS_GC_WORK_QUOTA 160 /* Allocations required before - garbage colllection */ - - #define EJS_PARSE_INCR 256 /* Growth factor */ - #define EJS_MAX_RECURSE 25 /* Sanity for maximum recursion */ - #define EJS_SMALL_OBJ_HASH_SIZE 11 /* Small object hash size */ - #define EJS_LIST_INCR 8 /* Growth increment for lists */ - #define EJS_MAX_BACKTRACE 10 /* Recursion limit for assert */ - -#else - #define EJS_GC_WORK_QUOTA 500 - - #define EJS_PARSE_INCR 1024 - #define EJS_MAX_RECURSE 100 - #define EJS_SMALL_OBJ_HASH_SIZE 11 - #define EJS_LIST_INCR 16 - #define EJS_MAX_BACKTRACE 25 - -#endif - -/* - * Allocation increments for the default interpreter - */ -#define EJS_DEFAULT_VAR_INC 8 /* Var allocation increment */ -#define EJS_DEFAULT_PROP_INC 96 /* Property allocation increment */ -#define EJS_DEFAULT_OBJ_INC 24 /* Object allocation increment */ -#define EJS_DEFAULT_STR_INC 64 /* Object allocation increment */ - -#define EJS_MIN_TIME_FOR_GC 300 /**< Need 1/3 sec for GC */ -#define EJS_GC_MIN_WORK_QUOTA 50 /**< Min to stop thrashing */ - -/* - * Allocation increments for all non-default interpreters - */ -#define EJS_VAR_INC 32 -#define EJS_PROP_INC 64 -#define EJS_OBJ_INC 64 -#define EJS_STR_INC 64 - -#define EJS_INC_FRAMES 8 /* Frame stack increment */ -#define EJS_MAX_FRAMES 64 /* Max frame stack */ - -/* - * Lexical analyser tokens - */ -#define EJS_TOK_ERR -1 /* Any error */ -#define EJS_TOK_LPAREN 1 /* ( */ -#define EJS_TOK_RPAREN 2 /* ) */ -#define EJS_TOK_IF 3 /* if */ -#define EJS_TOK_ELSE 4 /* else */ -#define EJS_TOK_LBRACE 5 /* { */ -#define EJS_TOK_RBRACE 6 /* } */ -#define EJS_TOK_LOGICAL 7 /* ||, &&, ! */ -#define EJS_TOK_EXPR 8 /* +, -, /, % */ -#define EJS_TOK_SEMI 9 /* ; */ -#define EJS_TOK_LITERAL 10 /* literal string */ -#define EJS_TOK_METHOD_NAME 11 /* methodName( */ -#define EJS_TOK_NEWLINE 12 /* newline white space */ -#define EJS_TOK_ID 13 /* Identifier */ -#define EJS_TOK_EOF 14 /* End of script */ -#define EJS_TOK_COMMA 15 /* Comma */ -#define EJS_TOK_VAR 16 /* var */ -#define EJS_TOK_ASSIGNMENT 17 /* = */ -#define EJS_TOK_FOR 18 /* for */ -#define EJS_TOK_INC_DEC 19 /* ++, -- */ -#define EJS_TOK_RETURN 20 /* return */ -#define EJS_TOK_PERIOD 21 /* . */ -#define EJS_TOK_LBRACKET 22 /* [ */ -#define EJS_TOK_RBRACKET 23 /* ] */ -#define EJS_TOK_NEW 24 /* new */ -#define EJS_TOK_DELETE 25 /* delete */ -#define EJS_TOK_IN 26 /* in */ -#define EJS_TOK_FUNCTION 27 /* function */ -#define EJS_TOK_NUMBER 28 /* Number */ -#define EJS_TOK_CLASS 29 /* class */ -#define EJS_TOK_EXTENDS 30 /* extends */ -#define EJS_TOK_PUBLIC 31 /* public */ -#define EJS_TOK_PRIVATE 32 /* private */ -#define EJS_TOK_PROTECTED 33 /* private */ -#define EJS_TOK_TRY 34 /* try */ -#define EJS_TOK_CATCH 35 /* catch */ -#define EJS_TOK_FINALLY 36 /* finally */ -#define EJS_TOK_THROW 37 /* throw */ -#define EJS_TOK_COLON 38 /* : */ -#define EJS_TOK_GET 39 /* get */ -#define EJS_TOK_SET 40 /* set */ -#define EJS_TOK_MODULE 41 /* module */ -#define EJS_TOK_EACH 42 /* each */ - -/* - * Expression operators - */ -#define EJS_EXPR_LESS 1 /* < */ -#define EJS_EXPR_LESSEQ 2 /* <= */ -#define EJS_EXPR_GREATER 3 /* > */ -#define EJS_EXPR_GREATEREQ 4 /* >= */ -#define EJS_EXPR_EQ 5 /* == */ -#define EJS_EXPR_NOTEQ 6 /* != */ -#define EJS_EXPR_PLUS 7 /* + */ -#define EJS_EXPR_MINUS 8 /* - */ -#define EJS_EXPR_DIV 9 /* / */ -#define EJS_EXPR_MOD 10 /* % */ -#define EJS_EXPR_LSHIFT 11 /* << */ -#define EJS_EXPR_RSHIFT 12 /* >> */ -#define EJS_EXPR_MUL 13 /* * */ -#define EJS_EXPR_ASSIGNMENT 14 /* = */ -#define EJS_EXPR_INC 15 /* ++ */ -#define EJS_EXPR_DEC 16 /* -- */ -#define EJS_EXPR_BOOL_COMP 17 /* ! */ - -/* - * Conditional operators - */ -#define EJS_COND_AND 1 /* && */ -#define EJS_COND_OR 2 /* || */ -#define EJS_COND_NOT 3 /* ! */ - -/** - * EJ Parsing States. Error and Return are be negative. - */ -#define EJS_STATE_ERR -1 /**< Error state */ -#define EJS_STATE_RET -2 /**< Return statement */ -#define EJS_STATE_EOF -3 /**< End of file */ -#define EJS_STATE_COND 2 /* Parsing a conditional stmt */ -#define EJS_STATE_COND_DONE 3 -#define EJS_STATE_RELEXP 4 /* Parsing a relational expr */ -#define EJS_STATE_RELEXP_DONE 5 -#define EJS_STATE_EXPR 6 /* Parsing an expression */ -#define EJS_STATE_EXPR_DONE 7 -#define EJS_STATE_STMT 8 /* Parsing General statement */ -#define EJS_STATE_STMT_DONE 9 -#define EJS_STATE_STMT_BLOCK_DONE 10 /* End of block "}" */ -#define EJS_STATE_ARG_LIST 11 /* Method arg list */ -#define EJS_STATE_ARG_LIST_DONE 12 -#define EJS_STATE_DEC_LIST 16 /* Declaration list */ -#define EJS_STATE_DEC_LIST_DONE 17 -#define EJS_STATE_DEC 18 /* Declaration statement */ -#define EJS_STATE_DEC_DONE 19 - -#define EJS_STATE_BEGIN EJS_STATE_STMT - -/* - * General parsing flags. - */ -#define EJS_FLAGS_EXE 0x1 /* Execute statements */ -#define EJS_FLAGS_LOCAL 0x2 /* Get local vars only */ -#define EJS_FLAGS_GLOBAL 0x4 /* Get global vars only */ -#define EJS_FLAGS_CREATE 0x8 /* Create var */ -#define EJS_FLAGS_ASSIGNMENT 0x10 /* In assignment stmt */ -#define EJS_FLAGS_DELETE 0x20 /* Deleting a variable */ -#define EJS_FLAGS_NEW 0x80 /* In a new stmt() */ -#define EJS_FLAGS_EXIT 0x100 /* Must exit */ -#define EJS_FLAGS_LHS 0x200 /* Left-hand-side of assignment */ -#define EJS_FLAGS_FORIN 0x400 /* In "for (v in ..." */ -#define EJS_FLAGS_CLASS_DEC 0x800 /* "class name [extends] name " */ -#define EJS_FLAGS_TRY 0x2000 /* In a try {} block */ -#define EJS_FLAGS_CATCH 0x4000 /* "catch (variable)" */ -#define EJS_FLAGS_DONT_GC 0x8000 /* Don't garbage collect */ -#define EJS_FLAGS_NO_ARGS 0x10000 /* Accessors don't use args */ -#define EJS_FLAGS_ENUM_HIDDEN 0x20000 /* Enumerate hidden fields */ -#define EJS_FLAGS_ENUM_BASE 0x40000 /* Enumerate base classes */ -#define EJS_FLAGS_TRACE_ARGS 0x80000 /* Support for printv */ -#define EJS_FLAGS_SHARED_SLAB 0x100000/* Using a shared slab */ - -/* - * Exceptions - */ -#define EJS_ARG_ERROR "ArgError" /**< Method argument error */ -#define EJS_ASSERT_ERROR "AssertError" /**< Assertion error */ -#define EJS_EVAL_ERROR "EvalError" /**< General evalation error */ -#define EJS_INTERNAL_ERROR "InternalError" /**< Internal error */ -#define EJS_IO_ERROR "IOError" /**< IO or data error */ -#define EJS_MEMORY_ERROR "MemoryError" /**< Memory allocation error */ -#define EJS_RANGE_ERROR "RangeError" /**< Data out of range (div by 0) */ -#define EJS_REFERENCE_ERROR "ReferenceError"/**< Object or property reference */ -#define EJS_SYNTAX_ERROR "SyntaxError" /**< Javascript syntax error */ -#define EJS_TYPE_ERROR "TypeError" /**< Wrong type supplied */ - -/* - * E4X - */ -#if BLD_FEATURE_EJS_E4X -#if BLD_FEATURE_SQUEEZE -#define E4X_BUF_SIZE 512 /* Initial buffer size for tokens */ -#define E4X_BUF_MAX (32 * 1024) /* Max size for tokens */ -#define E4X_MAX_NODE_DEPTH 24 /* Max nesting of tags */ -#else -#define E4X_BUF_SIZE 4096 -#define E4X_BUF_MAX (128 * 1024) -#define E4X_MAX_NODE_DEPTH 128 -#endif - -#define E4X_MAX_ELT_SIZE (E4X_BUF_MAX-1) -#define E4X_TEXT_PROPERTY "-txt" -#define E4X_TAG_NAME_PROPERTY "-tag" -#define E4X_COMMENT_PROPERTY "-com" -#define E4X_ATTRIBUTES_PROPERTY "-att" -#define E4X_PI_PROPERTY "-pi" -#define E4X_PARENT_PROPERTY "-parent" -#endif - -#if BLD_FEATURE_MULTITHREAD -/** - * Multithreaded lock function - */ -typedef void (*EjsLockFn)(void *lockData); -/** - * Multithreaded unlock function - */ -typedef void (*EjsUnlockFn)(void *lockData); -#endif - -/* - * Token limits - */ -#define EJS_MAX_LINE 128 /* Maximum input line buffer */ -#define EJS_MAX_TOKEN 640 /* Max input parse token */ -#define EJS_TOKEN_STACK 3 /* Put back token stack */ - -/* - * Putback token - */ - -typedef struct EjsToken { - char tokbuf[EJS_MAX_TOKEN]; - int tid; /* Token ID */ -} EjsToken; - -/* - * EJ evaluation block structure - */ -typedef struct EjsInput { - EjsToken putBack[EJS_TOKEN_STACK]; /* Put back token stack */ - int putBackIndex; /* Top of stack index */ - char line[EJS_MAX_LINE]; /* Current line */ - char *fileName; /* File or script name */ - int lineLength; /* Current line length */ - int lineNumber; /* Parse line number */ - int lineColumn; /* Column in line */ - struct EjsInput *next; /* Used for backtraces */ - const char *procName; /* Gives name in backtrace */ - const char *script; /* Input script for parsing */ - char *scriptServp; /* Next token in the script */ - int scriptSize; /* Length of script */ - char tokbuf[EJS_MAX_TOKEN]; /* Current token */ - int tid; /* Token ID */ - char *tokEndp; /* Pointer past end of token */ - char *tokServp; /* Pointer to next token char */ - struct EjsInput *nextInput; /* Free list of input structs */ -} EjsInput; - -/* - * Method call structure - */ -typedef struct EjsProc { - MprArray *args; /* Args for method */ - EjsVar *fn; /* Method definition */ - char *procName; /* Method name */ -} EjsProc; - - -/** - * @overview EJScript Service structure - * @description The EJScript service manages the overall language runtime. It - * is the factory that creates interpreter instances via ejsCreateInterp. - * The EJScript service creates a master interpreter that holds the - * standard language classes and properties. When user interpreters are - * created, they reference (without copying) the master interpreter to - * gain access to the standard classes and types. - * @stability Prototype. - * @library libejs. - * @see ejsOpenService, ejsCloseService, ejsCreateInterp, ejsDestoryInterp - */ -typedef struct EjsService { - EjsVar *globalClass; /* Global class */ - struct Ejs *master; /* Master Interp inherited by all */ -#if BLD_FEATURE_MULTITHREAD - EjsLockFn lock; - EjsUnlockFn unlock; - void *lockData; -#endif -} EjsService; - - -/* - * Memory statistics - */ -typedef struct EjsMemStats { - uint maxMem; - uint usedMem; -} EjsMemStats; - - -/* - * Garbage collection block alignment - */ -#define EJS_ALLOC_ALIGN(ptr) \ - (((ptr) + sizeof(void*) - 1) & ~(sizeof(void*) - 1)) - -/* - * Default GC tune factors - */ -#define EJS_GC_START_THRESHOLD (32 * 1024) - -/* - * The Garbage collector is a generational collector. It ages blocks and - * optimizes the mark / sweep algorithm to focus on new and recent blocks - */ -typedef enum EjsGeneration { - EJS_GEN_NEW = 0, - EJS_GEN_RECENT_1 = 1, - EJS_GEN_RECENT_2 = 2, - EJS_GEN_OLD = 3, - EJS_GEN_PERMANENT = 4, - EJS_GEN_MAX = 5, -} EjsGeneration; - -/* - * Garbage collector control - */ -typedef struct EjsGC { - bool enable; - bool enableDemandCollect; - bool enableIdleCollect; - /* - * maxMemory should be set to be 95% of the real max memory limit - */ - uint maxMemory; /* Above this, Throw Memory exception. */ - int workQuota; /* Quota of work before GC */ - int workDone; /* Count of allocations */ - int degraded; /* Have exceeded maxMemory */ - - /* - * Debug Levels 0-N (increases verbosity) - * 1 -- Sweep and collection count - * 2 -- Trace objects deleted - * 3 -- Trace objects marked - * 4 -- Print alloc report when needing a demand allocation - * - */ - int debugLevel; /* In debug mode */ - int collecting; /* Running garbage collection */ - uint collectionCount; /* Number of times GC ran */ -#if BLD_DEBUG - int gcIndent; /* Indent formatting */ - int objectsInUse; /* Objects currently reachable */ - int propertiesInUse; /* Properties currently reachable */ -#endif -} EjsGC; - -/* - * Slab memory allocation - */ -typedef struct EjsSlab { - uint allocIncrement; /* Growth increment in slab */ - uint size; /* Size of allocations */ - EjsGCLink freeList; /* Free list (only next ptr is used) */ - EjsObj *lastRecentBlock; /* Saved for GC age generations phase */ - EjsGCLink allocList[EJS_GEN_MAX]; /* Allocated block list */ - -#if BLD_FEATURE_ALLOC_STATS - uint totalAlloc; /* Total count of allocation calls */ - uint freeCount; /* Number of blocks on the slab freelist */ - uint allocCount; /* Number of allocated blocks */ - uint peakAllocated; /* Peak allocated */ - uint peakFree; /* Peak on the free list */ - uint totalReclaimed; /* Total blocks reclaimed on sweeps */ - uint totalSweeps; /* Total sweeps */ -#endif -} EjsSlab; - - -/** - * @overview EJ interpreter control structure. - * @description EJ allocates one control structure per active interpreter. - * The \ref ejsCreateInterp routine creates the Ejs structure and returns - * a reference to be used in subsequent EJ API calls. - * @stability Prototype. - * @library libejs. - * @see ejsCreateInterp, ejsDestroyInterp, ejsOpenService - */ -struct Ejs { - void *altHandle; /* Alternate callback handle */ - bool castAlloc; /* True if castTemp is allocated */ - char *castTemp; /* Temporary string for casting */ - char *currentClass; /* Current class name */ - EjsVar *currentObj; /* Ptr to current object */ - EjsVar *thisObject; /* Ptr to current "this" */ - EjsProperty *currentProperty; /* Ptr to current property */ - EjsGC gc; /* Garbage collector control */ - char *errorMsg; /* Error message */ - char *fileName; /* File or script name */ - int lineNumber; /* File line number */ - int scriptStatus; /* Status to exit() */ - int flags; /* Flags */ - MprArray *frames; /* List of variable frames */ - EjsVar *global; /* Global object */ - EjsVar *objectClass; /* Object class */ - int gotException; /* Exception thrown */ - EjsInput *input; /* Input evaluation block */ - int depth; /* Recursion depth */ - EjsVar *local; /* Local object */ - int maxDepth; /* Maximum depth for formatting */ - void *primaryHandle; /* primary callback handle */ - EjsProc *proc; /* Current method */ - int recurseCount; /* Recursion counter */ - EjsVar *result; /* Variable result */ - int tid; /* Current token id */ - char *token; /* Pointer to token string */ - EjsVar tokenNumber; /* Parsed number */ - EjsService *service; /* Service object */ - void *userData; /* Method user data */ - - EjsSlab *slabs; /* Memory allocation slabs */ - MprCtx slabAllocContext; /* Allocation context */ - EjsInput *inputList; /* Free list of input structs */ - -#if BLD_FEATURE_MULTITHREAD - EjsLockFn lock; /* Lock method */ - EjsUnlockFn unlock; /* Unlock method */ - void *lockData; /* Lock data argument */ -#endif -#define EJS_MAX_STACK (10 * 1024) - char stack[EJS_MAX_STACK]; /* Local variable stack */ - char *stkPtr; /* Local variable stack ptr */ - void *inputMarker; /* Recurse protection */ -}; - - -typedef struct EjsModule -{ - int dummy; -} EjsModule; - - -/* - * Method callback when using Alternate handles. GaCompat uses these and - * passes the web server request structure via the altHandle. - */ -typedef void *EjsHandle; -typedef int (*EjsAltCMethod)(Ejs *ejs, EjsHandle altHandle, - EjsVar *thisObj, int argc, EjsVar **argv); -typedef int (*EjsAltStringCMethod)(Ejs *ejs, EjsHandle altHandle, - EjsVar *thisObj, int argc, char **argv); - - -/* - * API Constants - */ -#define EJS_USE_OWN_SLAB 1 - -/******************************** Internal API ********************************/ -/* - * Ejs Lex - */ -extern int ejsLexOpenScript(Ejs *ejs, const char *script); -extern void ejsLexCloseScript(Ejs *ejs); -extern int ejsInitInputState(EjsInput *ip); -extern void ejsLexSaveInputState(Ejs *ejs, EjsInput* state); -extern void ejsLexFreeInputState(Ejs *ejs, EjsInput* state); -extern void ejsLexRestoreInputState(Ejs *ejs, EjsInput* state); -extern int ejsLexGetToken(Ejs *ejs, int state); -extern void ejsLexPutbackToken(Ejs *ejs, int tid, char *string); - -/* - * Parsing - */ -extern int ejsParse(Ejs *ejs, int state, int flags); -extern int ejsGetFlags(Ejs *ejs); - -/* - * Create variable scope blocks - */ -extern int ejsOpenBlock(Ejs *ejs); -extern int ejsSetBlock(Ejs *ejs, EjsVar *local); -extern int ejsCloseBlock(Ejs *ejs, int vid); -extern int ejsEvalBlock(Ejs *ejs, char *script, EjsVar *vp); -extern void ejsSetFileName(Ejs *ejs, const char *fileName); - -/* - * Class definitions - */ -extern EjsVar *ejsCreateSimpleClass(Ejs *ejs, EjsVar *baseClass, - const char *className); -extern int ejsDefineObjectClass(Ejs *ejs); -extern int ejsDefineArrayClass(Ejs *ejs); -extern int ejsDefineBooleanClass(Ejs *ejs); -extern int ejsDefineErrorClasses(Ejs *ejs); -extern int ejsDefineFileClass(Ejs *ejs); -extern int ejsDefineFileSystemClass(Ejs *ejs); -extern int ejsDefineHTTPClass(Ejs *ejs); -extern int ejsDefineFunctionClass(Ejs *ejs); -extern int ejsDefineNumberClass(Ejs *ejs); -extern int ejsDefineStringClass(Ejs *ejs); -extern int ejsDefineDateClass(Ejs *ejs); -extern int ejsDefineStandardClasses(Ejs *ejs); - -#if BLD_FEATURE_EJS_E4X -extern int ejsDefineXmlClasses(Ejs *ejs); -extern EjsVar *ejsCreateXml(Ejs *ejs); -#endif - -#if BLD_FEATURE_EJS_DB -extern int ejsDefineDbClasses(Ejs *ejs); -#endif - -/* - * System class definitions - */ -extern int ejsDefineSystemClasses(Ejs *ejs); -extern int ejsDefineSystemClass(Ejs *ejs); -extern int ejsDefineAppClass(Ejs *ejs); -extern int ejsDefineDebugClass(Ejs *ejs); -extern int ejsDefineLogClass(Ejs *ejs); -extern int ejsDefineMemoryClass(Ejs *ejs); -extern int ejsDefineGCClass(Ejs *ejs); -extern int ejsDefineGlobalProperties(Ejs *ejs); - -extern int ejsTermSystemClasses(Ejs *ejs); -extern void ejsTermHTTPClass(Ejs *ejs); - -extern int ejsCreateObjectModel(Ejs *ejs); - -/* - * Class constructors - */ -extern int ejsArrayConstructor(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **argv); -extern int ejsXmlConstructor(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **argv); -extern int ejsXmlListConstructor(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **argv); -extern int ejsBooleanConstructor(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **agv); -extern int ejsFunctionConstructor(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **agv); -extern int ejsNumberConstructor(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **argv); -extern int ejsStringConstructor(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **argv); -extern int ejsDateConstructor(Ejs *ejs, EjsVar *thisObj, - int argc, EjsVar **argv); - -/* - * Garbage collection - */ -extern void ejsGCInit(Ejs *ejs, int objInc, int propInc, int varInc, - int strInc); -extern int ejsIsTimeForGC(Ejs *ep, int timeTillNextEvent); - -extern bool ejsSetGCDebugLevel(Ejs *ep, int debugLevel); -extern void ejsSweepAll(Ejs *ep); - -extern EjsObj *ejsAllocObj(EJS_LOC_DEC(ejs, loc)); -extern EjsProperty *ejsAllocProperty(EJS_LOC_DEC(ejs, loc)); -extern EjsVar *ejsAllocVar(EJS_LOC_DEC(ejs, loc)); -extern void ejsFree(Ejs *ejs, void *ptr, int slabIndex); - -extern int ejsCollectGarbage(Ejs *ejs, int slabIndex); -extern int ejsIncrementalCollectGarbage(Ejs *ejs); - -#if BLD_DEBUG -extern void ejsDumpObjects(Ejs *ejs); -#endif - -#if BLD_FEATURE_ALLOC_STATS -extern void ejsPrintAllocReport(Ejs *ejs, bool printLeakReport); -#endif - -extern void ejsCleanInterp(Ejs *ejs, bool doStats); -extern void ejsSetInternalMethods(Ejs *ejs, EjsVar *op); -extern void ejsSetPrimaryHandle(Ejs *ep, void *primaryHandle); -extern void ejsSetAlternateHandle(Ejs *ep, void *alternateHandle); -extern void *ejsGetUserData(Ejs *ejs); - -/* - * Could possibly make these routines public - */ - -extern int ejsSetGCMaxMemory(Ejs *ep, uint maxMemory); -extern uint ejsGetUsedMemory(Ejs *ejs); -extern uint ejsGetAllocatedMemory(Ejs *ejs); -extern uint ejsGetAvailableMemory(Ejs *ejs); -extern char *ejsFormatStack(Ejs* ep);; - -/********************************* Prototypes *********************************/ -#if BLD_FEATURE_MULTITHREAD -extern int ejsSetServiceLocks(EjsService *sp, EjsLockFn lock, - EjsUnlockFn unlock, void *data); -#endif - -/* - * Ejs service and interpreter management - */ -extern EjsService *ejsOpenService(MprCtx ctx); -extern void ejsCloseService(EjsService *sp, bool doStats); - -extern Ejs *ejsCreateInterp(EjsService *sp, void *primaryHandle, - void *altHandle, EjsVar *global, bool useOwnSlab); -extern void ejsDestroyInterp(Ejs *ejs, bool doStats); - -extern Ejs *ejsGetMasterInterp(EjsService *sp); -extern EjsVar *ejsGetGlobalClass(Ejs *ejs); - -/* - * Module support - */ -extern EjsModule *ejsCreateModule(const char *name, const char *version, - int (*start)(EjsModule*), int (*stop)(EjsModule*)); - -/* - * Native Objects - */ - -void ejsSetNativeData(EjsVar *obj, void *data); -void ejsSetNativeHelpers(Ejs *ejs, EjsVar *nativeClass, - int (*createInstance)(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **argv), - void (*disposeInstance)(Ejs *ejs, EjsVar *thisObj), - bool (*hasProperty)(Ejs *ejs, EjsVar *thisObj, const char *prop), - int (*deleteProperty)(Ejs *ejs, EjsVar *thisObj, const char *prop), - int (*getProperty)(Ejs *ejs, EjsVar *thisObj, const char *prop, - EjsVar *dest), - int (*setProperty)(Ejs *ejs, EjsVar *thisObj, const char *prop, - EjsVar *value), - int (*doOperator)(Ejs *ejs, EjsVar *thisObj, EjsOp *op, EjsVar - *result, EjsVar *lhs, EjsVar *rhs, int *code) - ); - -/* - * Evaluation methods - */ -extern int ejsEvalFile(Ejs *ejs, const char *path, EjsVar *result); -extern int ejsEvalScript(Ejs *ejs, const char *script, EjsVar *result); -extern int ejsRunMethod(Ejs *ejs, EjsVar *obj, - const char *methodName, MprArray *args); -extern int ejsRunMethodCmd(Ejs *ejs, EjsVar *obj, - const char *methodName, const char *cmdFmt, ...); -extern EjsVar *ejsGetReturnValue(Ejs *ejs); - -extern EjsVar *ejsGetLocalObj(Ejs *ejs); -extern EjsVar *ejsGetGlobalObj(Ejs *ejs); - -/* - * Define a class in the specified interpreter. If used with the default - * interpeter, then the class is defined for all interpreters. - */ -extern EjsVar *ejsDefineClass(Ejs *ejs, const char *className, - const char *extends, EjsCMethod constructor); -extern EjsVar *ejsGetClass(Ejs *ejs, EjsVar *parentClass, - const char *className); - -extern const char *ejsGetClassName(EjsVar *obj); -extern const char *ejsGetBaseClassName(EjsVar *obj); - -extern bool ejsIsSubClass(EjsVar *target, EjsVar *baseClass); -extern EjsVar *ejsGetBaseClass(EjsVar *obj); -extern void ejsSetBaseClass(EjsVar *obj, EjsVar *baseClass); - - -#define ejsCreateSimpleObj(ejs, className) \ - ejsCreateSimpleObjInternal(EJS_LOC_ARGS(ejs), className) -extern EjsVar *ejsCreateSimpleObjInternal(EJS_LOC_DEC(ejs, loc), - const char *className); - -#define ejsCreateSimpleObjUsingClass(ejs, baseClass) \ - ejsCreateSimpleObjUsingClassInt(EJS_LOC_ARGS(ejs), \ - baseClass) -extern EjsVar *ejsCreateSimpleObjUsingClassInt(EJS_LOC_DEC(ejs, loc), - EjsVar *baseClass); - -/* - * This will create an object and call all required constructors - */ -extern EjsVar *ejsCreateObj(Ejs *ejs, EjsVar *obj, - const char *className, const char *constructorArgs); - -#define ejsCreateObjUsingArgv(ejs, obj, className, args) \ - ejsCreateObjUsingArgvInternal(EJS_LOC_ARGS(ejs), obj, \ - className, args) -extern EjsVar *ejsCreateObjUsingArgvInternal(EJS_LOC_DEC(ejs, loc), - EjsVar *obj, const char *className, MprArray *args); - -#define ejsCreateArray(ejs, size) \ - ejsCreateArrayInternal(EJS_LOC_ARGS(ejs), size) -extern EjsVar *ejsCreateArrayInternal(EJS_LOC_DEC(ejs, loc), - int size); - -/* - * Array methods. MOB -- need other array methods - */ -/* MOB -- spell out element */ -extern EjsVar *ejsAddArrayElt(Ejs *ejs, EjsVar *op, EjsVar *element, - EjsCopyDepth copyDepth); -/* - * Required: Array methods - * - array = obj.getMethods(); - array = obj.getProperties(); - - array.property.isPublic(); - array.property.isPrivate(); - array.property.isMethod(); - array.property.isEnumerable(); - array.property.isReadOnly(); - array.property.allowsNonUnique(); - array.property.getParent(); -*/ - -/* MOB -- should we have an API that takes a EjsCopyDepth */ -extern void ejsSetReturnValue(Ejs *ejs, EjsVar *vp); -extern void ejsSetReturnValueAndFree(Ejs *ejs, EjsVar *vp); -extern void ejsSetReturnValueToBoolean(Ejs *ejs, bool value); -extern void ejsSetReturnValueToBinaryString(Ejs *ejs, - const uchar *value, int len); -extern void ejsSetReturnValueToInteger(Ejs *ejs, int value); -extern void ejsSetReturnValueToNumber(Ejs *ejs, EjsNum value); -extern void ejsSetReturnValueToString(Ejs *ejs, const char *value); -extern void ejsSetReturnValueToUndefined(Ejs *ejs); - -/* - * Variable access and control. The fullName arg can contain "[]" and "." - */ -extern bool ejsGetBool(Ejs *ejs, const char *fullName, bool defaultValue); -extern int ejsGetInt(Ejs *ejs, const char *fullName, int defaultValue); -extern const char *ejsGetStr(Ejs *ejs, const char *fullName, - const char *defaultValue); -extern EjsVar *ejsGetVar(Ejs *ejs, const char *fullName); - -extern int ejsSetBool(Ejs *ejs, const char *fullName, bool value); -extern int ejsSetInt(Ejs *ejs, const char *fullName, int value); -extern int ejsSetStr(Ejs *ejs, const char *fullName, const char *value); -extern int ejsSetVar(Ejs *ejs, const char *fullName, const EjsVar *value); -extern int ejsSetVarAndFree(Ejs *ejs, const char *fullName, EjsVar *value); - -extern int ejsDeleteVar(Ejs *ejs, const char *fullName); - -/* - * Error handling - */ -extern void ejsError(Ejs *ejs, const char *errorType, const char *fmt, - ...) PRINTF_ATTRIBUTE(3,4); -/* MOB -- this should take no arguments */ -extern void ejsArgError(Ejs *ejs, const char *msg); -extern void ejsInternalError(Ejs *ejs, const char *msg); -extern void ejsMemoryError(Ejs *ejs); -extern void ejsSyntaxError(Ejs *ejs, const char *msg); - -/* - * Utility methods - */ -extern int ejsParseArgs(int argc, char **argv, const char *fmt, ...); - -extern void ejsExit(Ejs *ejs, int status); -extern bool ejsIsExiting(Ejs *ejs); -extern void ejsClearExiting(Ejs *ejs); - -extern bool ejsGotException(Ejs *ejs); - -/* MOB -- rename Method to Function */ -extern void ejsFreeMethodArgs(Ejs *ep, MprArray *args); -extern int ejsStrcat(Ejs *ep, EjsVar *dest, EjsVar *src); - -/* - * Debugging routines - */ -extern char *ejsGetErrorMsg(Ejs *ejs); -extern int ejsGetLineNumber(Ejs *ejs); -extern void ejsTrace(Ejs *ejs, const char *fmt, ...); - -/* - * Multithreaded lock routines - */ -#if BLD_FEATURE_MULTITHREAD -#define ejsLock(sp) if (sp->lock) { (sp->lock)(sp->lockData); } else -#define ejsUnlock(sp) if (sp->unlock) { (sp->unlock)(sp->lockData); } else -#else -#define ejsLock(sp) -#define ejsUnlock(sp) -#endif - -#ifdef __cplusplus -} -#endif -#endif /* _h_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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c b/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c deleted file mode 100644 index 58609adf3f..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * @file ejsClass.c - * @brief EJS class support - */ -/********************************* 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 ************************************/ -/* - * Internal API - * - * Routine to create a simple class object. This routine will create a - * stand-alone class object. Callers must insert this into the relevant - * "global" object for name resolution. From these class objects, instance - * objects may be created via the javascript "new" command. - * - * Users should use ejsDefineClass - */ - -EjsVar *ejsCreateSimpleClass(Ejs *ep, EjsVar *baseClass, const char *className) -{ - EjsProperty *pp; - EjsVar *classObj; - - /* - * Create an instance of an Object to act as the static class object - */ - classObj = ejsCreateSimpleObjUsingClass(ep, baseClass); - if (classObj == 0) { - mprAssert(classObj); - return 0; - } - ejsSetClassName(ep, classObj, className); - - /* - * Set the propotype property to point to this class. - * Note: this is a self reference so the alive bit will not be turned on. - */ - pp = ejsSetProperty(ep, classObj, "prototype", classObj); - ejsMakePropertyEnumerable(pp, 0); - - return classObj; -} - -/******************************************************************************/ -/* - * Define a class in the given interpreter. If parentClass is specified, the - * class is defined in the parent. Otherwise, the class will be defined - * locally/globally. ClassName and extends are full variable specs - * (may contain ".") - */ - -EjsVar *ejsDefineClass(Ejs *ep, const char *className, const char *extends, - EjsCMethod constructor) -{ - EjsVar *parentClass, *classObj, *baseClass, *vp; - char *name; - char *cp; - - /* - * If the className is a qualified name (with "."), then get the - * parent class name. - */ - name = mprStrdup(ep, className); - cp = strrchr(name, '.'); - if (cp != 0) { - *cp++ = '\0'; - className = cp; - parentClass = ejsFindProperty(ep, 0, 0, ep->global, ep->local, name, 0); - if (parentClass == 0 || parentClass->type != EJS_TYPE_OBJECT) { - mprError(ep, MPR_LOC, "Can't find class's parent class %s", name); - mprFree(name); - return 0; - } - - } else { - /* - * Simple class name without a "." so create the class locally - * if a local scope exists, otherwise globally. - */ - parentClass = (ep->local) ? ep->local : ep->global; - } - - if (parentClass == 0) { - mprError(ep, MPR_LOC, "Can't find parent class"); - mprFree(name); - return 0; - } - - /* OPT should use function that doesn't parse [] . */ - baseClass = ejsGetClass(ep, 0, extends); - if (baseClass == 0) { - mprAssert(baseClass); - mprFree(name); - return 0; - } - - classObj = ejsCreateSimpleClass(ep, baseClass, className); - if (classObj == 0) { - mprAssert(classObj); - mprFree(name); - return 0; - } - - if (constructor) { - ejsDefineCMethod(ep, classObj, className, constructor, 0); - } - - ejsSetPropertyAndFree(ep, parentClass, className, classObj); - - vp = ejsGetPropertyAsVar(ep, parentClass, className); - mprFree(name); - - return vp; -} - -/******************************************************************************/ -/* - * Find a class and return the property defining the class. ClassName may - * contain "." and is interpreted relative to obj. Obj is typically some - * parent object, ep->local or ep->global. If obj is null, then the global - * space is used. - */ - -EjsVar *ejsGetClass(Ejs *ep, EjsVar *obj, const char *className) -{ - EjsVar *vp; - - mprAssert(ep); - - /* - * Search first for a constructor of the name of class - * global may not be defined yet. - */ - if (obj) { - vp = ejsFindProperty(ep, 0, 0, obj, 0, className, 0); - - } else { - mprAssert(ep->global); - vp = ejsFindProperty(ep, 0, 0, ep->global, ep->local, className, 0); - } - if (vp == 0 || vp->type != EJS_TYPE_OBJECT) { - return 0; - } - - /* - * Return a reference to the prototype (self) reference. This - * ensures that even if "obj" is deleted, this reference will remain - * usable. - */ - return ejsGetPropertyAsVar(ep, vp, "prototype"); -} - -/******************************************************************************/ -/* - * Return the class name of a class or object - */ - -const char *ejsGetClassName(EjsVar *vp) -{ - EjsObj *obj; - - mprAssert(vp); - mprAssert(vp->type == EJS_TYPE_OBJECT); - mprAssert(vp->objectState->baseClass); - - if (vp == 0 || !ejsVarIsObject(vp)) { - return 0; - } - obj = vp->objectState; - - return obj->className; -} - -/******************************************************************************/ -/* - * Return the class name of an objects underlying class - * If called on an object, it returns the base class. - * If called on a class, it returns the base class for the class. - */ - -const char *ejsGetBaseClassName(EjsVar *vp) -{ - EjsObj *obj; - - mprAssert(vp); - mprAssert(vp->type == EJS_TYPE_OBJECT); - mprAssert(vp->objectState->baseClass); - - if (vp == 0 || !ejsVarIsObject(vp)) { - return 0; - } - obj = vp->objectState; - if (obj->baseClass == 0) { - return 0; - } - mprAssert(obj->baseClass->objectState); - - return obj->baseClass->objectState->className; -} - -/******************************************************************************/ - -EjsVar *ejsGetBaseClass(EjsVar *vp) -{ - if (vp == 0 || !ejsVarIsObject(vp) || vp->objectState == 0) { - mprAssert(0); - return 0; - } - return vp->objectState->baseClass; -} - -/******************************************************************************/ - -void ejsSetBaseClass(EjsVar *vp, EjsVar *baseClass) -{ - if (vp == 0 || !ejsVarIsObject(vp) || vp->objectState == 0) { - mprAssert(0); - return; - } - vp->objectState->baseClass = baseClass; -} - -/******************************************************************************/ - -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c b/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c deleted file mode 100644 index 74b57de4d0..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejsCmd.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * @file ejsCmd.c - * @brief Embedded JavaScript (EJS) command line program. - * @overview - */ -/********************************* 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 && !BREW - -/************************************ Defines *********************************/ - -#define EJS_MAX_CMD_LINE (16 * 1024) -#define EJS_MAX_SCRIPT (4 * 1024 * 1024) -#define EJS_MAX_RESULT_SIZE (4 * 1024 * 1024) -#define EJS_PROMPT "ejs> " - -/****************************** Forward Declarations **************************/ - -static int parseFile(EjsService *ejsService, Ejs *ejs, const char *fileName, - const char *testName, MprFile *testLogFile); -static int ifConsole(); - -static int interactiveUse(MprApp *app, Ejs *ejs, FILE *input, - char *fileName); -static char *readCmd(MprApp *app, FILE *input); - -static int memoryFailure(MprApp *app, uint size, uint total, bool granted); - -static int isConsole = 0; -static int traceCmds = 0; -static int stats = 0; -static int verbose = 0; - -/************************************ Main ************************************/ - -int main(int argc, char *argv[]) -{ - MprApp *app; - const char *programName; - MprFile *testLogFile; - EjsService *ejsService; - Ejs *ejs; - char *commandLine; - const char *testName; - char *argp, *cmd, *testLog; - int i, rc, nextArg, err, len, firstArg, iterations, debugLevel; - - app = mprInit(memoryFailure); - - isConsole = ifConsole(); - programName = mprGetBaseName(argv[0]); - debugLevel = 0; - - ejsService = ejsOpenService(app); - if (ejsService == 0) { - mprError(app, MPR_LOC, "Can't initialize the EJS service."); - return -1; - } - - err = 0; - iterations = 1; - stats = 0; - testLog = getenv("TEST_LOG"); - testLogFile = 0; - testName = 0; - - for (nextArg = 1; nextArg < argc; nextArg++) { - argp = argv[nextArg]; - if (*argp != '-') { - break; - } - if (strcmp(argp, "--debug") == 0) { - if (nextArg >= argc) { - err++; - } else { - debugLevel = atoi(argv[++nextArg]); - } - - } else if (strcmp(argp, "--stats") == 0) { - stats++; - - } else if (strcmp(argp, "--trace") == 0) { - traceCmds++; - - } else if (strcmp(argp, "--iterations") == 0) { - if (nextArg >= argc) { - err++; - } else { - iterations = atoi(argv[++nextArg]); - } - - } else if (strcmp(argp, "--log") == 0) { - /* Get file to log test results to when using ejs as a test shell */ - if (nextArg >= argc) { - err++; - } else { - testLog = argv[++nextArg]; - } - - } else if (strcmp(argp, "--testName") == 0) { - if (nextArg >= argc) { - err++; - } else { - testName = argv[++nextArg]; - } - - } else if (strcmp(argp, "-v") == 0) { - verbose++; - - } else if (strcmp(argp, "-vv") == 0) { - verbose += 2; - - } else if (strcmp(argp, "--verbose") == 0) { - verbose += 2; - - } else { - err++; - break; - } - if (err) { - mprErrorPrintf(app, - "Usage: %s [options] files... or\n" - " %s < file or\n" - " %s or\n" - " Switches:\n" - " --iterations num # Number of iterations to eval file\n" - " --stats # Output stats on exit\n" - " --testName name # Set the test name", - programName, programName, programName); - return -1; - } - } - - if (testName) { - i = 0; - commandLine = 0; - len = mprAllocStrcat(MPR_LOC_ARGS(app), &commandLine, 0, " ", - mprGetBaseName(argv[i++]), NULL); - for (; i < argc; i++) { - len = mprReallocStrcat(MPR_LOC_ARGS(app), &commandLine, 0, len, - " ", argv[i], NULL); - } - mprPrintf(app, " %s\n", commandLine); - } - if (testLog) { - testLogFile = mprOpen(app, testLog, - O_CREAT | O_APPEND | O_WRONLY | O_TEXT, 0664); - if (testLogFile == 0) { - mprError(app, MPR_LOC, "Can't open %s", testLog); - return MPR_ERR_CANT_OPEN; - } - mprFprintf(testLogFile, "\n %s\n", commandLine); - } - - ejs = ejsCreateInterp(ejsService, 0, 0, 0, 0); - if (ejs == 0) { - mprError(app, MPR_LOC, "Can't create EJS interpreter"); - ejsCloseService(ejsService, stats); - if (testLogFile) { - mprClose(testLogFile); - } - mprTerm(app, stats); - exit(-1); - } - - if (debugLevel > 0) { - ejsSetGCDebugLevel(ejs, debugLevel); - } - - rc = 0; - - if (nextArg < argc) { - /* - * Process files supplied on the command line - */ - firstArg = nextArg; - for (i = 0; i < iterations; i++) { - for (nextArg = firstArg; nextArg < argc; nextArg++) { - rc = parseFile(ejsService, ejs, argv[nextArg], testName, - testLogFile); - if (rc < 0) { - return rc; - } - } - } - if (testName) { - if (verbose == 1) { - mprPrintf(app, "\n"); - } - if (verbose <= 1) { - mprPrintf(app, " # PASSED all tests for \"%s\"\n", testName); - } - } - - } else if (! isConsole) { - /* - * Read a script from stdin - */ - cmd = readCmd(app, stdin); - - ejsSetFileName(ejs, "stdin"); - - rc = ejsEvalScript(ejs, cmd, 0); - if (rc < 0) { - mprPrintf(app, "ejs: Error: %s\n", ejsGetErrorMsg(ejs)); - } - mprFree(cmd); - - } else { - /* - * Interactive use. Read commands from the command line. - */ - rc = interactiveUse(app, ejs, stdin, "stdin"); - } - - /* - * Cleanup. Do stats if required. - */ - if (ejs) { - ejsCleanInterp(ejs, 0); - ejsCleanInterp(ejs->service->master, 0); - ejsDestroyInterp(ejs, 0); - } - - ejsCloseService(ejsService, stats); - - if (testLogFile) { - mprClose(testLogFile); - } - - mprTerm(app, stats); - return rc; -} - -/******************************************************************************/ - -static int parseFile(EjsService *ejsService, Ejs *ejs, const char *fileName, - const char *testName, MprFile *testLogFile) -{ - int rc; - - if (testName && verbose == 1) { - mprPrintf(ejs, "."); - } - if (verbose > 1) { - mprPrintf(ejs, "File: %s\n", fileName); - } - - rc = ejsEvalFile(ejs, fileName, 0); - - if (testName) { - char fileBuf[MPR_MAX_FNAME], *cp; - mprStrcpy(fileBuf, sizeof(fileBuf), fileName); - if ((cp = strstr(fileBuf, ".ejs")) != 0) { - *cp = '\0'; - } - if (rc == 0) { - if (verbose > 1) { - mprPrintf(ejs, " # PASSED test \"%s.%s\"\n", testName, - fileBuf); - } - if (testLogFile) { - mprFprintf(testLogFile, " # PASSED test \"%s.%s\"\n", - testName, fileBuf); - } - - } else { - - mprPrintf(ejs, "FAILED test \"%s.%s\"\nDetails: %s\n", - testName, fileBuf, ejsGetErrorMsg(ejs)); - - if (testLogFile) { - mprFprintf(testLogFile, - "FAILED test \"%s.%s\"\nDetails: %s\n", - testName, fileBuf, ejsGetErrorMsg(ejs)); - } - } - } else if (rc < 0) { - mprPrintf(ejs, "ejs: %sIn file \"%s\"\n", - ejsGetErrorMsg(ejs), fileName); - } - return rc; -} - -/******************************************************************************/ - -static char *readCmd(MprApp *app, FILE *input) -{ - char line[EJS_MAX_CMD_LINE]; - char *cmd; - int len, cmdLen; - - cmd = 0; - cmdLen = 0; - - line[sizeof(line) - 1] = '\0'; - - while (1) { - - if (fgets(line, sizeof(line) - 1, input) == NULL) { - break; - } - - len = strlen(line); - - if (line[len - 1] == '\\') { - line[len - 1] = '\0'; - } - cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT, - cmdLen, 0, line, NULL); - } - return cmd; -} - -/******************************************************************************/ - -static int interactiveUse(MprApp *app, Ejs *ejs, FILE *input, char *fileName) -{ - EjsVar result; - char line[EJS_MAX_CMD_LINE]; - char *cmd, *buf; - int len, cmdLen, rc; - - cmd = 0; - cmdLen = 0; - - line[sizeof(line) - 1] = '\0'; - - ejsSetFileName(ejs, "console"); - - while (! ejsIsExiting(ejs)) { - - if (isConsole) { - write(1, EJS_PROMPT, strlen(EJS_PROMPT)); - } - - if (fgets(line, sizeof(line) - 1, input) == NULL) { - break; - } - - len = strlen(line); - while (len > 0 && - (line[len - 1] == '\n' || line[len - 1] == '\r')) { - len--; - line[len] = '\0'; - } - - if (line[len - 1] == '\\') { - line[len - 1] = '\0'; - cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT, - cmdLen, 0, line, NULL); - - } else { - - cmdLen = mprReallocStrcat(MPR_LOC_ARGS(app), &cmd, EJS_MAX_SCRIPT, - cmdLen, 0, line, NULL); - - - if (traceCmds) { - mprPrintf(ejs, "# %s\n", cmd); - } - - if (cmd[0] == 0x4 || cmd[0] == 0x26 || strcmp(cmd, "quit") == 0) { - ejsExit(ejs, 0); - - } else if ((rc = ejsEvalScript(ejs, cmd, &result)) < 0) { - - mprPrintf(app, "ejs: Error: %s\n", ejsGetErrorMsg(ejs)); - - if (! isConsole) { - return rc; - } - - } else { - if (isConsole || traceCmds) { - buf = ejsVarToString(ejs, &result); - mprPrintf(ejs, "%s\n", buf); - } - } - mprFree(cmd); - cmd = 0; - cmdLen = 0; - } - } - return 0; -} - -/******************************************************************************/ - -static int ifConsole() -{ -#if WIN - INPUT_RECORD irec[1]; - int records = 0; - - if (PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE), irec, 1, - &records) != 0) { - return 1; - } -#else - return isatty(0); -#endif - return 0; -} - -/******************************************************************************/ - -static int memoryFailure(MprApp *app, uint size, uint total, bool granted) -{ - if (!granted) { - mprPrintf(app, "Can't allocate memory block of size %d\n", size); - mprPrintf(app, "Total memory used %d\n", total); - exit(255); - } - mprPrintf(app, "Memory request for %d bytes exceeds memory red-line\n", - size); - mprPrintf(app, "Total memory used %d\n", total); - return 0; -} - -/******************************************************************************/ - -#else -void ejsCmdLineDummy() {} - -/******************************************************************************/ -#endif /* BLD_FEATURE_EJS */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsGarbage.c b/source4/lib/appweb/ejs-2.0/ejs/ejsGarbage.c deleted file mode 100755 index 264da05721..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejsGarbage.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * @file ejsGarbage.c - * @brief EJS Garbage collector. - * @overview This implements a generational mark and sweep collection scheme. - */ -/********************************* Copyright **********************************/ -/* - * @copy default - * - * Copyright (c) Mbedthis Software LLC, 2003-2006. 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 - -/****************************** Forward Declarations **************************/ - -static void mark(Ejs *ep); -static void markObjByVar(Ejs *ep, EjsVar *op); -static void markObj(EjsObj *obj); -static void markPerm(Ejs *ep, uint gen); -static int sweep(Ejs *ep, uint gen); -static EjsGCLink *ejsAlloc(EJS_LOC_DEC(ep, loc), int slabIndex); -static void ejsGracefulDegrade(Ejs *ep); -static void resetMarks(Ejs *ep, EjsSlab *slab); - -#if FUTURE -static void ageGenerations(Ejs *ep); -#endif - -#if BLD_DEBUG && (!BREW || BREW_SIMULATOR) -uint breakAddr; -#endif - -/************************************* Code ***********************************/ - -void ejsGCInit(Ejs *ep, int objInc, int propInc, int varInc, int strInc) -{ - EjsSlab *slab; - - if (ep->service && ep->service->globalClass) { - ep->service->globalClass->objectState->gcMarked = 1; - } - - slab = &ep->slabs[EJS_SLAB_OBJ]; - slab->allocIncrement = objInc; - slab->size = EJS_ALLOC_ALIGN(sizeof(EjsObj)); - - slab = &ep->slabs[EJS_SLAB_PROPERTY]; - slab->allocIncrement = propInc; - slab->size = EJS_ALLOC_ALIGN(sizeof(EjsProperty)); - - slab = &ep->slabs[EJS_SLAB_VAR]; - slab->allocIncrement = varInc; - slab->size = EJS_ALLOC_ALIGN(sizeof(EjsVar)); - - /* - * Initialize GC. - * Enable GC both idle and demand collections. - * Set no limits and garbage collect if the slabs are - * empty and we have used more than the THRESHOLD of ram. - */ - ep->gc.debugLevel = 0; - ep->gc.enable = 1; - ep->gc.enableIdleCollect = 1; - ep->gc.enableDemandCollect = 1; - ep->gc.workQuota = EJS_GC_WORK_QUOTA; - ep->gc.maxMemory = 0; -} - - -/******************************************************************************/ -#if BLD_FEATURE_ALLOC_STATS - -void ejsPrintAllocReport(Ejs *ep, bool printLeakReport) -{ - EjsSlab *slab; - char *name; - int slabIndex, isObj; - - for (slabIndex = 0; slabIndex < EJS_SLAB_MAX; slabIndex++) { - slab = &ep->slabs[slabIndex]; - if (slabIndex == EJS_SLAB_VAR) { - name = "var"; - } else if (slabIndex == EJS_SLAB_PROPERTY) { - name = "prop"; - } else { - name = "obj"; - } - mprLog(ep, 0, " "); - mprLog(ep, 0, " GC \"%s\" local slab", name); - mprLog(ep, 0, " Total blocks %14d", - slab->allocCount + slab->freeCount); - mprLog(ep, 0, " Block size %14d", slab->size); - mprLog(ep, 0, " Slab RAM allocated %14d", - (slab->allocCount + slab->freeCount) * slab->size); - mprLog(ep, 0, " Slab RAM in use %14d", - slab->allocCount * slab->size); - mprLog(ep, 0, " Blocks in use %14d", slab->allocCount); - mprLog(ep, 0, " Free blocks %14d", slab->freeCount); - mprLog(ep, 0, " Peak allocated %14d", slab->peakAllocated); - mprLog(ep, 0, " Peak free %14d", slab->peakFree); - mprLog(ep, 0, " Total allocations %14d", slab->totalAlloc); - mprLog(ep, 0, " Total blocks reclaimed %14d", slab->totalReclaimed); - mprLog(ep, 0, " Total sweeps %14d", slab->totalSweeps); - mprLog(ep, 0, " Allocation inc %14d", slab->allocIncrement); - } - - mprLog(ep, 0, " "); - mprLog(ep, 0, " Total EJS memory in use %10d", ejsGetUsedMemory(ep)); - mprLog(ep, 0, " Total EJS memory allocated %10d", - ejsGetAllocatedMemory(ep)); - - if (printLeakReport) { - mprLog(ep, 0, " "); - for (slabIndex = 0; slabIndex < EJS_SLAB_MAX; slabIndex++) { - int size; - - slab = &ep->slabs[slabIndex]; - - isObj = 0; - mprLog(ep, 0, " "); - if (slabIndex == EJS_SLAB_VAR) { - name = "var"; - size = sizeof(EjsVar); - } else if (slabIndex == EJS_SLAB_PROPERTY) { - name = "prop"; - size = sizeof(EjsProperty); - } else { - name = "obj"; - size = sizeof(EjsObj); - isObj++; - } -#if BLD_FEATURE_ALLOC_LEAK_TRACK -{ - EjsGCLink *lp; - EjsObj *obj; - int count; - - mprLog(ep, 0, "EJS Leak Report for \"%s\"", name); - count = 0; - - for (lp = slab->allocList[0].next; lp; lp = lp->next) { - mprLog(ep, 0, " %-20s %10d", lp->allocatedBy, size); - if (isObj) { - obj = (EjsObj*) lp; - mprLog(ep, 0, " %-20s %10d %s %s", - lp->allocatedBy, size, - obj->permanent ? "permanent" : "", - obj->alive ? "alive" : "" - ); - } else { - mprLog(ep, 0, " %-20s %10d", lp->allocatedBy, - size); - } - count++; - } - mprLog(ep, 0, " Total blocks %14d", count); -} -#endif - } - mprLog(ep, 0, " "); - } -} - -#endif -/******************************************************************************/ -/* - * Slab allocator - */ - -static EjsGCLink *ejsAlloc(EJS_LOC_DEC(ep, loc), int slabIndex) -{ - EjsSlab *slab; - EjsGCLink *block; - EjsGC *gc; - uint allocatedMemory; - int i; - - mprStackCheck(ep); - - if (slabIndex < 0 || slabIndex >= EJS_SLAB_MAX) { - mprAssert(0); - return 0; - } - - /* - * See if the slab has some free blocks - */ - slab = &ep->slabs[slabIndex]; - if ((block = slab->freeList.next) == 0) { - - allocatedMemory = ejsGetAllocatedMemory(ep); - gc = &ep->gc; - - /* - * No blocks available. If demand collection is enabled, try - * to garbage collect first. We collect if we have done a good - * work quota or we are over the max memory limit. - */ - if (slabIndex != EJS_SLAB_VAR && - ep->gc.enable && ep->gc.enableDemandCollect) { - if ((ep->gc.workDone > ep->gc.workQuota) || - (gc->maxMemory > 0 && allocatedMemory > gc->maxMemory)) { - -#if DEBUG_USE_ONLY - if (ep->gc.debugLevel > 0) { - mprLog(ep, 0, "Need GC, EJS RAM %d, MPR RAM %d\n", - allocatedMemory, mprGetAllocatedMemory(ep)); - if (ep->gc.debugLevel > 4) { - ejsPrintAllocReport(ep, 0); - } - } -#endif - if (ejsCollectGarbage(ep, slabIndex) == 0) { - block = slab->freeList.next; - } - } - } - - if (block == 0) { - if (gc->maxMemory > 0 && allocatedMemory > gc->maxMemory) { - /* - * We are above the max memory limit. We will fail this - * memory allocation, but allow subsequent allocations to - * permit error recovery. We gracefully degrade by setting - * slab chunk sizes to 1. This minimizes real memory - * consumption. This allows us to create - * an exception block to be created by upper layers. - */ - if (! gc->degraded) { - ejsGracefulDegrade(ep); - return 0; - } - } - - /* - * Still non available, so allocate more memory for a set of blocks - * OPT -- should bypass mprAlloc. Need mprMalloc. - */ - block = mprAlloc(ep->slabAllocContext, - slab->size * slab->allocIncrement); - if (block == 0) { - /* - * Now we're in trouble. We should really never get here - * as the graceful degrade will have signaled a memory - * allocation failure. - */ - mprAssert(block != 0); - return 0; - } - - /* - * Chain all the blocks together onto the slab free list - */ - for (i = slab->allocIncrement - 1; i >= 0; i--) { - block->next = slab->freeList.next; -#if BLD_DEBUG - block->magic = EJS_MAGIC_FREE; -#endif - slab->freeList.next = block; - block = (EjsGCLink*) ((char*) block + slab->size); - } - - block = slab->freeList.next; - -#if BLD_FEATURE_ALLOC_STATS - slab->freeCount += slab->allocIncrement; - if (slab->freeCount > slab->peakFree) { - slab->peakFree = slab->freeCount; - } -#endif - } - } - - /* - * We use block to point to the user data in the block. We only - * store the magic number (if debug). No other data is stored in the - * user block. - */ -#if BLD_DEBUG - mprAssert(block->magic == EJS_MAGIC_FREE); -#endif - - /* - * Remove from the free list - */ - slab->freeList.next = block->next; - - /* - * Zero block - */ - memset(block, 0, slab->size); - -#if BLD_DEBUG - block->magic = EJS_MAGIC; -#endif - -#if BLD_FEATURE_ALLOC_STATS - slab->totalAlloc++; - if (++slab->allocCount > slab->peakAllocated) { - slab->peakAllocated = slab->allocCount; - } - slab->freeCount--; -#endif - -#if BLD_DEBUG && (!BREW || BREW_SIMULATOR) - if ((uint) block == breakAddr) { - mprBreakpoint(MPR_LOC, "Watched Block"); - } -#endif - return block; -} - - -/******************************************************************************/ - -EjsObj *ejsAllocObj(EJS_LOC_DEC(ep, loc)) -{ - EjsObj *obj; - EjsSlab *slab; - - obj = (EjsObj*) ejsAlloc(EJS_LOC_PASS(ep, loc), EJS_SLAB_OBJ); - - /* - * Add to the allocated block list for the New generation. - */ - if (obj) { - slab = &ep->slabs[EJS_SLAB_OBJ]; - obj->gc.next = slab->allocList[EJS_GEN_NEW].next; - -#if BLD_FEATURE_ALLOC_LEAK_TRACK - obj->gc.allocatedBy = loc; -#endif - - obj->ejs = ep; - slab->allocList[EJS_GEN_NEW].next = (EjsGCLink*) obj; - - ep->gc.workDone++; - } - - return obj; -} - - -/******************************************************************************/ - -EjsProperty *ejsAllocProperty(EJS_LOC_DEC(ep, loc)) -{ - EjsProperty *prop; - - prop = (EjsProperty*) ejsAlloc(EJS_LOC_PASS(ep, loc), EJS_SLAB_PROPERTY); - mprAssert(prop); - - if (prop) { - prop->var.type = EJS_TYPE_NULL; - prop->var.isProperty = 1; -#if BLD_FEATURE_ALLOC_LEAK_TRACK - prop->var.gc.allocatedBy = loc; -#endif - } - return prop; -} - - -/******************************************************************************/ - -EjsVar *ejsAllocVar(EJS_LOC_DEC(ep, loc)) -{ - EjsVar *vp; - - vp = (EjsVar*) ejsAlloc(EJS_LOC_PASS(ep, loc), EJS_SLAB_VAR); - mprAssert(vp); - - if (vp) { -#if BLD_FEATURE_ALLOC_LEAK_TRACK - EjsSlab *slab; - vp->gc.allocatedBy = loc; - slab = &ep->slabs[EJS_SLAB_VAR]; - vp->gc.next = slab->allocList[EJS_GEN_NEW].next; - slab->allocList[EJS_GEN_NEW].next = (EjsGCLink*) vp; -#endif -#if BLD_DEBUG - vp->propertyName = 0; -#endif - } - return vp; -} - - -/******************************************************************************/ -/* - * Return the block back to the relevant slab - */ - -void ejsFree(Ejs *ep, void *ptr, int slabIndex) -{ - EjsSlab *slab; - EjsGCLink *block; - - mprAssert(ep); - mprAssert(ptr); - - if (slabIndex < 0 || slabIndex >= EJS_SLAB_MAX) { - mprAssert(slabIndex >= 0 && slabIndex < EJS_SLAB_MAX); - return; - } - slab = &ep->slabs[slabIndex]; - -#if BLD_FEATURE_ALLOC_LEAK_TRACK - if (slabIndex == EJS_SLAB_VAR) { - EjsVar *vp, *np, *prev; - - /* - * Remove the block rom the alloc list. WARNING: this is slow - * and should not be used in production code. - */ - vp = (EjsVar*) ptr; - prev = 0; - for (np = (EjsVar*) slab->allocList[0].next; np; - np = (EjsVar*) np->gc.next) { - if (vp == np) { - if (prev) { - prev->gc.next = (EjsGCLink*) np->gc.next; - } else { - slab->allocList[0].next = (EjsGCLink*) np->gc.next; - } - break; - } - prev = np; - } - if (np == 0) { - mprAssert(0); - } - } -#endif - - /* - * Insert into the free list. Only use the next ptr - */ - block = (EjsGCLink*) ptr; - -#if BLD_DEBUG -#if !BREW || BREW_SIMULATOR - if ((uint) block == breakAddr) { - mprBreakpoint(MPR_LOC, "Watched Block"); - } -#endif - mprAssert(block->magic == EJS_MAGIC); - block->magic = EJS_MAGIC_FREE; -#endif - - block->next = slab->freeList.next; - slab->freeList.next = block; - -#if BLD_FEATURE_ALLOC_STATS - slab->allocCount--; - if (++slab->freeCount >= slab->peakFree) { - slab->peakFree = slab->freeCount; - } - slab->totalReclaimed++; - if (slabIndex != 2) { - slabIndex = slabIndex; - } -#endif -} - -/******************************************************************************/ -/* - * Mark an object as being in-use. Traverse all properties for referenced - * objects and base classes. - */ - -static void markObjByVar(Ejs *ep, EjsVar *obj) -{ - EjsProperty *pp; - EjsVar *vp, *baseClass; - - mprAssert(ep); - mprAssert(obj); - - obj->objectState->gcMarked = 1; - -#if BLD_DEBUG - if (ep->gc.debugLevel >= 3) { - int indent = min(ep->gc.gcIndent * 2, 32); - mprLog(ep, 0, "%.*s %-24s %.*s 0x%08X", - indent, " ", - obj->propertyName, - 32 - indent, "................................ ", - (uint) obj->objectState); - ep->gc.gcIndent++; - } - ep->gc.objectsInUse++; -#endif - - /* - * Traverse all referenced objects - * OPT -- optimize by directly accessing the object links and not using - * ejsGetFirst/NextProperty. Then just examine objects - * OPT -- first property in global is global. Should optimize this. - */ - pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL); - while (pp) { - vp = ejsGetVarPtr(pp); - if (vp->type == EJS_TYPE_OBJECT) { - if (!vp->objectState->gcMarked) { -#if FUTURE - /* - * OPT -- we can use the dirty bit on objects to avoid - * visiting permanent objects that are clean. If so, don't - * forget the else case below. - */ - obj = vp->objectState; - if ((!obj->alive && !obj->permanent) || obj->dirty) -#endif - markObjByVar(ep, vp); - } - - } else { -#if BLD_DEBUG - if (ep->gc.debugLevel >= 3) { - int indent = min(ep->gc.gcIndent * 2, 32); - mprLog(ep, 0, "%.*s %-24s %.*s %s", - indent, " ", - vp->propertyName, - 32 - indent, "................................ ", - ejsGetVarTypeAsString(vp)); - } - ep->gc.propertiesInUse++; -#endif - } - pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); - } - - /* - * Traverse the base class - */ - baseClass = obj->objectState->baseClass; - if (baseClass) { - mprAssert(baseClass->type == EJS_TYPE_OBJECT); - mprAssert(baseClass->objectState); - if (baseClass->objectState) { - if (! baseClass->objectState->gcMarked) { - markObjByVar(ep, baseClass); - } - } - } -#if BLD_DEBUG - if (ep->gc.debugLevel >= 3) { - ep->gc.gcIndent--; - } -#endif -} - - -/******************************************************************************/ -/* - * Mark phase. Examine all variable frames and the return result. - */ - -static void mark(Ejs *ep) -{ - EjsVar *vp; - int i; - -#if BLD_DEBUG - if (ep->gc.debugLevel >= 3) { - mprLog(ep, 0, " "); - mprLog(ep, 0, "GC: Marked Blocks:"); - } -#endif - - if (ep->frames) { - for (i = 0; i < mprGetItemCount(ep->frames); i++) { - - vp = (EjsVar*) mprGetItem(ep->frames, i); - mprAssert(vp->type == EJS_TYPE_OBJECT); - - if (! vp->objectState->gcMarked) { - markObjByVar(ep, vp); - } - } - } - - vp = ep->result; - if (vp && vp->type == EJS_TYPE_OBJECT && ! vp->objectState->gcMarked) { - markObjByVar(ep, vp); - } - - vp = ep->currentObj; - if (vp && vp->type == EJS_TYPE_OBJECT && ! vp->objectState->gcMarked) { - markObjByVar(ep, vp); - } - - vp = ejsGetVarPtr(ep->currentProperty); - if (vp && vp->type == EJS_TYPE_OBJECT && ! vp->objectState->gcMarked) { - markObjByVar(ep, vp); - } - - /* - * OPT -- we could mark master as "mark permanent" somehow and - * then we would not need to walk the master objects. - */ - if (ep->slabAllocContext == ep->service->master) { - if (ep->service->master->global) { - markObjByVar(ep, ep->service->master->global); - } - } - -#if BLD_DEBUG - if (ep->gc.debugLevel >= 3) { - mprLog(ep, 0, " "); - } -#endif -} - - -/******************************************************************************/ -#if UNUSED - -static void resetMark(EjsVar *obj) -{ - EjsProperty *pp; - EjsVar *vp, *baseClass; - - obj->objectState->gcMarked = 0; - obj->objectState->visited = 1; - - pp = ejsGetFirstProperty(obj, EJS_ENUM_ALL); - while (pp) { - vp = ejsGetVarPtr(pp); - if (vp->type == EJS_TYPE_OBJECT && !vp->objectState->visited) { - resetMark(vp); - } - pp = ejsGetNextProperty(pp, EJS_ENUM_ALL); - } - - baseClass = obj->objectState->baseClass; - if (baseClass) { - mprAssert(baseClass->type == EJS_TYPE_OBJECT); - mprAssert(baseClass->objectState); - if (baseClass->objectState) { - if (! baseClass->objectState->visited) { - resetMark(baseClass); - } - } - } - obj->objectState->visited = 0; -} - -/******************************************************************************/ -/* - * Mark phase. Examine all variable frames and the return result. - */ - -static void resetAllMarks(Ejs *ep) -{ - EjsVar *vp; - int i; - - for (i = 0; i < mprGetItemCount(ep->frames); i++) { - vp = (EjsVar*) mprGetItem(ep->frames, i); - resetMark(vp); - } - - if (ep->result && ep->result->type == EJS_TYPE_OBJECT && - ! ep->result->objectState->gcMarked) { - resetMark(ep->result); - } -} - -#endif -/******************************************************************************/ -/* - * Sweep up the garbage - */ - -static void resetMarks(Ejs *ep, EjsSlab *slab) -{ - EjsVar *vp; - EjsObj *obj; - int gen, i; - - for (gen = EJS_GEN_NEW; gen < EJS_GEN_MAX; gen++) { - obj = (EjsObj*) slab->allocList[gen].next; - for (; obj; obj = (EjsObj*) obj->gc.next) { - obj->gcMarked = 0; - obj->visited = 0; - } - } - - if (ep->frames) { - for (i = 0; i < mprGetItemCount(ep->frames); i++) { - - vp = (EjsVar*) mprGetItem(ep->frames, i); - mprAssert(vp->type == EJS_TYPE_OBJECT); - - vp->objectState->gcMarked = 0; - vp->objectState->visited = 0; - } - } - - if (ep->result && ep->result->type == EJS_TYPE_OBJECT) { - ep->result->objectState->gcMarked = 0; - } -} - -/******************************************************************************/ -/* - * Mark all permanent and non-alive objects - */ - -static void markPerm(Ejs *ep, uint gen) -{ - EjsSlab *slab; - EjsObj *obj; - - slab = &ep->slabs[EJS_SLAB_OBJ]; - - for (obj = (EjsObj*) slab->allocList[gen].next; obj; ) { - - if (! obj->gcMarked) { - if (!obj->alive || obj->permanent) { - markObj(obj); - } - } - obj = (EjsObj*) obj->gc.next; - - } -} - -/******************************************************************************/ - -static void markObj(EjsObj *obj) -{ - EjsProperty *pp; - EjsPropLink *lp, *head; - EjsObj *op; - - mprAssert(obj); - - obj->gcMarked = 1; - - head = &obj->link; - for (lp = head->next; lp != head; lp = lp->next) { - - pp = ejsGetPropertyFromLink(lp); - - if (pp->var.type == EJS_TYPE_OBJECT) { - op = pp->var.objectState; - if (op != 0 && !op->gcMarked) { - markObj(op); - } - } - } -} - -/******************************************************************************/ -/* - * Sweep up the garbage. Return the number of objects freed. - */ - -static int sweep(Ejs *ep, uint gen) -{ - EjsSlab *slab; - EjsObj *obj, *next, *prev; - int count; - - slab = &ep->slabs[EJS_SLAB_OBJ]; - - /* - * Examine allocated objects in the specified generation (only). - * NOTE: we only sweep object allocated to this interpreter and so - * we do not sweep any permanent objects in the default interpreter. - */ - prev = 0; - count = 0; - for (obj = (EjsObj*) slab->allocList[gen].next; obj; obj = next) { - - next = (EjsObj*) obj->gc.next; - -#if BLD_DEBUG && (!BREW || BREW_SIMULATOR) - if ((uint) obj == breakAddr) { - mprBreakpoint(MPR_LOC, "Watched Block"); - } -#endif - - /* - * If object has not been marked inuse and is not a permanent - * object, then free it. - */ - if (! obj->gcMarked && obj->alive && !obj->permanent) { - -#if BLD_DEBUG - if (ep->gc.debugLevel >= 2) { - if (obj->objName) { - mprLog(ep, 0, "GC: destroy %-18s %10d, %8X", - obj->objName, (uint) obj, (uint) obj); - } else { - mprLog(ep, 0, "GC: destroy UNKNOWN %x", (uint) obj); - } - } -#endif - if (ejsDestroyObj(ep, obj) < 0) { - prev = obj; - obj->gcMarked = 0; - continue; - } - - if (prev) { - prev->gc.next = (EjsGCLink*) next; - } else { - slab->allocList[gen].next = (EjsGCLink*) next; - } - count++; - - } else { - prev = obj; - /* Reset for next time */ - obj->gcMarked = 0; - } - } - - if (gen == (EJS_GEN_OLD - 1)) { - slab->lastRecentBlock = prev; - } -#if BLD_FEATURE_ALLOC_STATS - slab->totalSweeps++; -#endif -#if BLD_DEBUG - if (ep->gc.debugLevel > 0) { - mprLog(ep, 0, "GC: Sweep freed %d objects", count); - } -#endif - return count; -} - -/******************************************************************************/ -/* - * Sweep all variables - */ - -void ejsSweepAll(Ejs *ep) -{ - EjsSlab *slab; - EjsObj *obj, *next, *prev; - int gen; - - slab = &ep->slabs[EJS_SLAB_OBJ]; - - for (gen = EJS_GEN_NEW; gen < EJS_GEN_MAX; gen++) { - prev = 0; - for (obj = (EjsObj*) slab->allocList[gen].next; obj; obj = next) { - next = (EjsObj*) obj->gc.next; - ejsDestroyObj(ep, obj); - } - break; - } -} - -/******************************************************************************/ - -bool ejsObjIsCollectable(EjsVar *vp) -{ - if (vp == 0 || !ejsVarIsObject(vp)) { - return 0; - } - return (vp->objectState->alive && !vp->objectState->permanent); -} - -/******************************************************************************/ -#if FUTURE - -static void ageGenerations(Ejs *ep) -{ - EjsSlab *slab; - EjsGCLink *oldList; - int gen; - - slab = &ep->slabs[EJS_SLAB_OBJ]; - - /* - * Age all blocks. First append all (old - 1) blocks onto the old - * alloc list - */ - oldList = &slab->allocList[EJS_GEN_OLD]; - - if (slab->lastRecentBlock) { - slab->lastRecentBlock->gc.next = oldList->next; - oldList->next = (EjsGCLink*) slab->lastRecentBlock; - } - - /* - * Now simply copy all allocation lists up one generation - */ - for (gen = EJS_GEN_OLD - 1; gen > 0; gen--) { - slab->allocList[gen] = slab->allocList[gen - 1]; - } - slab->allocList[0].next = 0; -} - -#endif -/******************************************************************************/ -/* - * Collect the garbage. This is a mark and sweep over all possible objects. - * If an object is not referenced, it and all contained properties will be - * freed. If a slabIndex is provided, the collection halts when a block is - * available for allocation on that slab. - * - * Return 0 if memory is now available after collecting garbage. Otherwise, - * return MPR_ERR_MEMORY. - */ - -int ejsCollectGarbage(Ejs *ep, int slabIndex) -{ - EjsGeneration gen; - - if (ep->flags & EJS_FLAGS_DONT_GC) { - return -1; - } - - /* - * Prevent destructors invoking the garbage collector - */ - if (ep->gc.collecting) { - return 0; - } - ep->gc.collecting = 1; - - resetMarks(ep, &ep->slabs[EJS_SLAB_OBJ]); - - /* - * Examine each generation of objects starting with the most recent - * generation. Stop scanning when we have a free block to use. - */ - for (gen = EJS_GEN_NEW; gen < EJS_GEN_MAX; gen++) { - - if (slabIndex >= 0 && ep->slabs[slabIndex].freeList.next) { - break; - } - - /* - * FUTURE OPT. Should mark objects in new generation and those - * with a dirty bit set in older generations. Don't need to mark - * entire heap. But how to keep list of dirty objects. - */ - mark(ep); - markPerm(ep, gen); - sweep(ep, gen); - - /* FUTURE - not using generations yet */ - break; - } - - /* - * FUTURE -- not using generations yet. - * - * ageGenerations(ep); - */ - - ep->gc.workDone = 0; - ep->gc.collecting = 0; - - return (gen < EJS_GEN_MAX) ? 0 : MPR_ERR_MEMORY; -} - - -/******************************************************************************/ -/* - * Should be called when the app has been idle for a little while and when it - * is likely to be idle a bit longer. Call ejsIsTimeForGC to see if this is - * true. Return the count of objects collected . - */ - -int ejsIncrementalCollectGarbage(Ejs *ep) -{ - int count; - - if (ep->gc.collecting) { - return 0; - } - - ep->gc.collecting = 1; - - resetMarks(ep, &ep->slabs[EJS_SLAB_OBJ]); - mark(ep); - - /* Not generational yet */ - count = sweep(ep, EJS_GEN_NEW); - - ep->gc.collecting = 0; - ep->gc.workDone = 0; - - return count; -} - -/******************************************************************************/ -#if BLD_DEBUG - -void ejsDumpObjects(Ejs *ep) -{ - int oldDebugLevel; - - mprLog(ep, 0, "Dump of objects in use\n"); - - oldDebugLevel = ep->gc.debugLevel; - - ep->gc.debugLevel = 3; - ep->gc.objectsInUse = 0; - ep->gc.propertiesInUse = 0; - ep->gc.collecting = 1; - - resetMarks(ep, &ep->slabs[EJS_SLAB_OBJ]); - mark(ep); - - ep->gc.collecting = 0; - ep->gc.debugLevel = oldDebugLevel; - - mprLog(ep, 0, "%d objects and %d properties in use", - ep->gc.objectsInUse, ep->gc.propertiesInUse); - mprLog(ep, 0, "%d object bytes, %d property bytes and %d total", - (int) (ep->gc.objectsInUse * sizeof(EjsObj)), - (int) (ep->gc.propertiesInUse * sizeof(EjsProperty)), - (int) ((ep->gc.objectsInUse * sizeof(EjsObj) + - ep->gc.propertiesInUse * sizeof(EjsProperty)))); -} - -#endif -/******************************************************************************/ -/* - * Return true if there is time to do a garbage collection and if we will - * benefit from it. - */ - -int ejsIsTimeForGC(Ejs *ep, int timeTillNextEvent) -{ - EjsGC *gc; - - if (timeTillNextEvent < EJS_MIN_TIME_FOR_GC) { - /* - * Not enough time to complete a collection - */ - return 0; - } - - gc = &ep->gc; - - /* - * Return if we haven't done enough work to warrant a collection - * Trigger a little short of the work quota to try to run GC before - * a demand allocation requires it. - */ - if (!gc->enable || !gc->enableIdleCollect || - (gc->workDone < (gc->workQuota - EJS_GC_MIN_WORK_QUOTA))) { - return 0; - } - -#if UNUSED - mprLog(ep, 0, "Time for GC. Work done %d, time till next event %d", - gc->workDone, timeTillNextEvent); -#endif - return 1; -} - -/******************************************************************************/ -/* - * Return the amount of memory in use by EJS - */ - -uint ejsGetUsedMemory(Ejs *ep) -{ -#if BLD_FEATURE_ALLOC_STATS - EjsSlab *slab; - int i, totalMemory, slabMemory; - - totalMemory = 0; - for (i = 0; i < EJS_SLAB_MAX; i++) { - slab = &ep->slabs[i]; - slabMemory = slab->allocCount * slab->size; - totalMemory += slabMemory; - } - return totalMemory; -#else - return 0; -#endif -} - -/******************************************************************************/ -/* - * Return the amount of memory allocated by EJS - */ - -uint ejsGetAllocatedMemory(Ejs *ep) -{ -#if BLD_FEATURE_ALLOC_STATS - EjsSlab *slab; - int i, totalMemory, slabMemory; - - totalMemory = 0; - for (i = 0; i < EJS_SLAB_MAX; i++) { - slab = &ep->slabs[i]; - slabMemory = (slab->allocCount + slab->freeCount) * slab->size; - totalMemory += slabMemory; - } - return totalMemory; -#else - return 0; -#endif -} - -/******************************************************************************/ -/* - * On a memory allocation failure, go into graceful degrade mode. Set all - * slab allocation chunk increments to 1 so we can create an exception block - * to throw. - */ - -static void ejsGracefulDegrade(Ejs *ep) -{ - EjsSlab *slab; - int i; - - mprLog(ep, 1, "WARNING: Memory almost depleted. In graceful degrade mode"); - for (i = 0; i < EJS_SLAB_MAX; i++) { - slab = &ep->slabs[i]; - slab->allocIncrement = 8; - } - ep->gc.degraded = 1; -} - -/******************************************************************************/ - -int ejsSetGCDebugLevel(Ejs *ep, int debugLevel) -{ - int old; - - old = ep->gc.debugLevel; - ep->gc.debugLevel = debugLevel; - return old; -} - -/******************************************************************************/ - -int ejsSetGCMaxMemory(Ejs *ep, uint maxMemory) -{ - int old; - - old = ep->gc.maxMemory; - ep->gc.maxMemory = maxMemory; - - return old; -} - -/******************************************************************************/ - -bool ejsBlockInUseInt(EjsVar *vp) -{ - if (vp) { -#if BLD_DEBUG - if (vp->gc.magic != EJS_MAGIC) { - return 0; - } - if (vp->type == EJS_TYPE_OBJECT && vp->objectState && - vp->objectState->gc.magic != EJS_MAGIC) { - return 0; - } -#endif - return 1; - } - return 1; -} - -/******************************************************************************/ -#else -void ejsGarbageDummy() {} - -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsLex.c b/source4/lib/appweb/ejs-2.0/ejs/ejsLex.c deleted file mode 100644 index fbfee6e4d5..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejsLex.c +++ /dev/null @@ -1,1033 +0,0 @@ -/* - * @file ejsLex.c - * @brief EJS Lexical Analyser - * @overview EJS lexical analyser. This implementes a lexical analyser - * for a subset of the JavaScript language. - */ -/********************************* Copyright **********************************/ -/* - * @copy default.g - * - * Copyright (c) Mbedthis Software LLC, 2003-2006. 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 "ejs.h" - -#if BLD_FEATURE_EJS - -/****************************** Forward Declarations **************************/ - -static int getLexicalToken(Ejs *ep, int state); -static int tokenAddChar(Ejs *ep, int c); -static int inputGetc(Ejs *ep); -static void inputPutback(Ejs *ep, int c); -static int charConvert(Ejs *ep, int base, int maxDig); -static void parseNumber(Ejs *ep, EjsType type); - -/************************************* Code ***********************************/ -/* - * Open a new input script - */ - -int ejsLexOpenScript(Ejs *ep, const char *script) -{ - EjsInput *ip; - - mprAssert(ep); - mprAssert(script); - - if ((ip = mprAllocTypeZeroed(ep, EjsInput)) == NULL) { - return MPR_ERR_MEMORY; - } - ip->next = ep->input; - ep->input = ip; - ip->procName = ep->proc ? ep->proc->procName : NULL; - ip->fileName = ep->fileName ? ep->fileName : NULL; - -/* - * Create the parse token buffer and script buffer - */ - ip->tokServp = ip->tokbuf; - ip->tokEndp = ip->tokbuf; - - ip->script = script; - ip->scriptSize = strlen(script); - ip->scriptServp = (char*) ip->script; - - ip->lineNumber = 1; - ip->lineColumn = 0; - - ip->putBackIndex = -1; - - return 0; -} - -/******************************************************************************/ -/* - * Close the input script - */ - -void ejsLexCloseScript(Ejs *ep) -{ - EjsInput *ip; - - mprAssert(ep); - - ip = ep->input; - mprAssert(ip); - ep->input = ip->next; - - mprFree(ip); -} - -/******************************************************************************/ -/* - * Initialize an input state structure - */ - -int ejsInitInputState(EjsInput *ip) -{ - mprAssert(ip); - - memset(ip, 0, sizeof(*ip)); - ip->putBackIndex = -1; - - return 0; -} -/******************************************************************************/ -/* - * Save the input state - */ - -void ejsLexSaveInputState(Ejs *ep, EjsInput *state) -{ - EjsInput *ip; - int i; - - mprAssert(ep); - - ip = ep->input; - mprAssert(ip); - - *state = *ip; - - for (i = 0; i <= ip->putBackIndex; i++) { - mprStrcpy(state->putBack[i].tokbuf, EJS_MAX_TOKEN, - ip->putBack[i].tokbuf); - state->putBack[i].tid = ip->putBack[i].tid; - } - - mprStrcpy(state->line, sizeof(state->line), ip->line); - - state->lineColumn = ip->lineColumn; - state->lineNumber = ip->lineNumber; -} - -/******************************************************************************/ -/* - * Restore the input state - */ - -void ejsLexRestoreInputState(Ejs *ep, EjsInput *state) -{ - EjsInput *ip; - EjsToken *tp; - int i; - - mprAssert(ep); - mprAssert(state); - - ip = ep->input; - mprAssert(ip); - - mprStrcpy(ip->tokbuf, sizeof(ip->tokbuf), state->tokbuf); - ip->tokServp = state->tokServp; - ip->tokEndp = state->tokEndp; - - ip->script = state->script; - ip->scriptServp = state->scriptServp; - ip->scriptSize = state->scriptSize; - - ip->putBackIndex = state->putBackIndex; - for (i = 0; i <= ip->putBackIndex; i++) { - tp = &ip->putBack[i]; - tp->tid = state->putBack[i].tid; - mprStrcpy(tp->tokbuf, sizeof(tp->tokbuf), state->putBack[i].tokbuf); - } - - mprStrcpy(ip->line, sizeof(ip->line), state->line); - - ip->lineColumn = state->lineColumn; - ip->lineNumber = state->lineNumber; -} - -/******************************************************************************/ -/* - * Free a saved input state - */ - -void ejsLexFreeInputState(Ejs *ep, EjsInput *state) -{ - mprAssert(ep); - mprAssert(state); - - state->putBackIndex = -1; - state->lineColumn = 0; -} - -/******************************************************************************/ -/* - * Get the next EJS token - */ - -int ejsLexGetToken(Ejs *ep, int state) -{ - mprAssert(ep); - - ep->tid = getLexicalToken(ep, state); - return ep->tid; -} - -/******************************************************************************/ - -/* - * Check for reserved words "if", "else", "var", "for", "delete", "function", - * "class", "extends", "public", "private", "protected", "try", "catch", - * "finally", "throw", "return", "get", "set", "this", "module", "each" - * - * The "new" and "in" reserved words are handled below. The "true", "false", - * "null" "typeof" and "undefined" reserved words are handled as global - * objects. - * - * Other reserved words not supported: - * "break", "case", "continue", "default", "do", - * "instanceof", "switch", "while", "with" - * - * ECMA extensions reserved words (not supported): - * "abstract", "boolean", "byte", "char", "const", - * "debugger", "double", "enum", "export", - * "final", "float", "goto", "implements", "import", "int", - * "interface", "long", "native", "package", - * "short", "static", "super", "synchronized", "transient", "volatile" - * - * FUTURE -- use a hash lookup - */ - -static int checkReservedWord(Ejs *ep, int state, int c, int tid) -{ - /* FUTURE -- probably should return for all tokens != EJS_TOK_ID */ - /* FUTURE -- Should have a hash for this. MUCH faster. */ - - if (!isalpha(ep->token[0]) || tid == EJS_TOK_LITERAL) { - return tid; - } - if (state == EJS_STATE_STMT) { - /* FUTURE OPT -- convert to hash lookup */ - if (strcmp(ep->token, "if") == 0) { - inputPutback(ep, c); - return EJS_TOK_IF; - } else if (strcmp(ep->token, "else") == 0) { - inputPutback(ep, c); - return EJS_TOK_ELSE; - } else if (strcmp(ep->token, "var") == 0) { - inputPutback(ep, c); - return EJS_TOK_VAR; - } else if (strcmp(ep->token, "new") == 0) { - inputPutback(ep, c); - return EJS_TOK_NEW; - } else if (strcmp(ep->token, "for") == 0) { - inputPutback(ep, c); - return EJS_TOK_FOR; - } else if (strcmp(ep->token, "delete") == 0) { - inputPutback(ep, c); - return EJS_TOK_DELETE; - } else if (strcmp(ep->token, "function") == 0) { - inputPutback(ep, c); - return EJS_TOK_FUNCTION; - } else if (strcmp(ep->token, "class") == 0) { - inputPutback(ep, c); - return EJS_TOK_CLASS; - } else if (strcmp(ep->token, "module") == 0) { - inputPutback(ep, c); - return EJS_TOK_MODULE; - } else if (strcmp(ep->token, "extends") == 0) { - inputPutback(ep, c); - return EJS_TOK_EXTENDS; - } else if (strcmp(ep->token, "try") == 0) { - inputPutback(ep, c); - return EJS_TOK_TRY; - } else if (strcmp(ep->token, "catch") == 0) { - inputPutback(ep, c); - return EJS_TOK_CATCH; - } else if (strcmp(ep->token, "finally") == 0) { - inputPutback(ep, c); - return EJS_TOK_FINALLY; - } else if (strcmp(ep->token, "throw") == 0) { - inputPutback(ep, c); - return EJS_TOK_THROW; - } else if (strcmp(ep->token, "public") == 0) { - inputPutback(ep, c); - return EJS_TOK_PUBLIC; - } else if (strcmp(ep->token, "protected") == 0) { - inputPutback(ep, c); - return EJS_TOK_PROTECTED; - } else if (strcmp(ep->token, "private") == 0) { - inputPutback(ep, c); - return EJS_TOK_PRIVATE; - } else if (strcmp(ep->token, "get") == 0) { - inputPutback(ep, c); - return EJS_TOK_GET; - } else if (strcmp(ep->token, "set") == 0) { - inputPutback(ep, c); - return EJS_TOK_SET; - } else if (strcmp(ep->token, "extends") == 0) { - inputPutback(ep, c); - return EJS_TOK_EXTENDS; - } else if (strcmp(ep->token, "try") == 0) { - inputPutback(ep, c); - return EJS_TOK_TRY; - } else if (strcmp(ep->token, "catch") == 0) { - inputPutback(ep, c); - return EJS_TOK_CATCH; - } else if (strcmp(ep->token, "finally") == 0) { - inputPutback(ep, c); - return EJS_TOK_FINALLY; - } else if (strcmp(ep->token, "throw") == 0) { - inputPutback(ep, c); - return EJS_TOK_THROW; - } else if (strcmp(ep->token, "public") == 0) { - inputPutback(ep, c); - return EJS_TOK_PUBLIC; - } else if (strcmp(ep->token, "protected") == 0) { - inputPutback(ep, c); - return EJS_TOK_PROTECTED; - } else if (strcmp(ep->token, "private") == 0) { - inputPutback(ep, c); - return EJS_TOK_PRIVATE; - } else if (strcmp(ep->token, "get") == 0) { - inputPutback(ep, c); - return EJS_TOK_GET; - } else if (strcmp(ep->token, "set") == 0) { - inputPutback(ep, c); - return EJS_TOK_SET; - } else if (strcmp(ep->token, "each") == 0) { - inputPutback(ep, c); - return EJS_TOK_EACH; - } else if (strcmp(ep->token, "return") == 0) { - if ((c == ';') || (c == '(')) { - inputPutback(ep, c); - } - return EJS_TOK_RETURN; - } - - } else if (state == EJS_STATE_EXPR) { - if (strcmp(ep->token, "new") == 0) { - inputPutback(ep, c); - return EJS_TOK_NEW; - } else if (strcmp(ep->token, "in") == 0) { - inputPutback(ep, c); - return EJS_TOK_IN; - } else if (strcmp(ep->token, "function") == 0) { - inputPutback(ep, c); - return EJS_TOK_FUNCTION; - } - - } else if (state == EJS_STATE_DEC) { - if (strcmp(ep->token, "extends") == 0) { - inputPutback(ep, c); - return EJS_TOK_EXTENDS; - } - } - return tid; -} - -/******************************************************************************/ -/* - * Get the next EJS token - */ - -static int getLexicalToken(Ejs *ep, int state) -{ - EjsType type; - EjsInput *ip; - int done, tid, c, quote, style, idx, isHex; - - mprAssert(ep); - ip = ep->input; - mprAssert(ip); - - ep->tid = -1; - tid = -1; - type = BLD_FEATURE_NUM_TYPE_ID; - isHex = 0; - - /* - * Use a putback tokens first. Don't free strings as caller needs access. - */ - if (ip->putBackIndex >= 0) { - idx = ip->putBackIndex; - tid = ip->putBack[idx].tid; - ep->token = (char*) ip->putBack[idx].tokbuf; - tid = checkReservedWord(ep, state, 0, tid); - ip->putBackIndex--; - return tid; - } - ep->token = ip->tokServp = ip->tokEndp = ip->tokbuf; - *ip->tokServp = '\0'; - - if ((c = inputGetc(ep)) < 0) { - return EJS_TOK_EOF; - } - - /* - * Main lexical analyser - */ - for (done = 0; !done; ) { - switch (c) { - case -1: - return EJS_TOK_EOF; - - case ' ': - case '\t': - case '\r': - do { - if ((c = inputGetc(ep)) < 0) - break; - } while (c == ' ' || c == '\t' || c == '\r'); - break; - - case '\n': - return EJS_TOK_NEWLINE; - - case '(': - tokenAddChar(ep, c); - return EJS_TOK_LPAREN; - - case ')': - tokenAddChar(ep, c); - return EJS_TOK_RPAREN; - - case '[': - tokenAddChar(ep, c); - return EJS_TOK_LBRACKET; - - case ']': - tokenAddChar(ep, c); - return EJS_TOK_RBRACKET; - - case '.': - tokenAddChar(ep, c); - return EJS_TOK_PERIOD; - - case '{': - tokenAddChar(ep, c); - return EJS_TOK_LBRACE; - - case '}': - tokenAddChar(ep, c); - return EJS_TOK_RBRACE; - - case '+': - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - if (c != '+' ) { - inputPutback(ep, c); - tokenAddChar(ep, EJS_EXPR_PLUS); - return EJS_TOK_EXPR; - } - tokenAddChar(ep, EJS_EXPR_INC); - return EJS_TOK_INC_DEC; - - case '-': - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - if (c != '-' ) { - inputPutback(ep, c); - tokenAddChar(ep, EJS_EXPR_MINUS); - return EJS_TOK_EXPR; - } - tokenAddChar(ep, EJS_EXPR_DEC); - return EJS_TOK_INC_DEC; - - case '*': - tokenAddChar(ep, EJS_EXPR_MUL); - return EJS_TOK_EXPR; - - case '%': - tokenAddChar(ep, EJS_EXPR_MOD); - return EJS_TOK_EXPR; - - case '/': - /* - * Handle the division operator and comments - */ - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - if (c != '*' && c != '/') { - inputPutback(ep, c); - tokenAddChar(ep, EJS_EXPR_DIV); - return EJS_TOK_EXPR; - } - style = c; - /* - * Eat comments. Both C and C++ comment styles are supported. - */ - while (1) { - if ((c = inputGetc(ep)) < 0) { - if (style == '/') { - return EJS_TOK_EOF; - } - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - if (c == '\n' && style == '/') { - break; - } else if (c == '*') { - c = inputGetc(ep); - if (style == '/') { - if (c == '\n') { - break; - } - } else { - if (c == '/') { - break; - } - } - } - } - /* - * Continue looking for a token, so get the next character - */ - if ((c = inputGetc(ep)) < 0) { - return EJS_TOK_EOF; - } - break; - - case '<': /* < and <= */ - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - if (c == '<') { - tokenAddChar(ep, EJS_EXPR_LSHIFT); - return EJS_TOK_EXPR; - } else if (c == '=') { - tokenAddChar(ep, EJS_EXPR_LESSEQ); - return EJS_TOK_EXPR; - } - tokenAddChar(ep, EJS_EXPR_LESS); - inputPutback(ep, c); - return EJS_TOK_EXPR; - - case '>': /* > and >= */ - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - if (c == '>') { - tokenAddChar(ep, EJS_EXPR_RSHIFT); - return EJS_TOK_EXPR; - } else if (c == '=') { - tokenAddChar(ep, EJS_EXPR_GREATEREQ); - return EJS_TOK_EXPR; - } - tokenAddChar(ep, EJS_EXPR_GREATER); - inputPutback(ep, c); - return EJS_TOK_EXPR; - - case '=': /* "==" */ - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - if (c == '=') { - tokenAddChar(ep, EJS_EXPR_EQ); - return EJS_TOK_EXPR; - } - inputPutback(ep, c); - return EJS_TOK_ASSIGNMENT; - - case '!': /* "!=" or "!"*/ - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - if (c == '=') { - tokenAddChar(ep, EJS_EXPR_NOTEQ); - return EJS_TOK_EXPR; - } - inputPutback(ep, c); - tokenAddChar(ep, EJS_EXPR_BOOL_COMP); - return EJS_TOK_EXPR; - - case ';': - tokenAddChar(ep, c); - return EJS_TOK_SEMI; - - case ',': - tokenAddChar(ep, c); - return EJS_TOK_COMMA; - - case ':': - tokenAddChar(ep, c); - return EJS_TOK_COLON; - - case '|': /* "||" */ - if ((c = inputGetc(ep)) < 0 || c != '|') { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - tokenAddChar(ep, EJS_COND_OR); - return EJS_TOK_LOGICAL; - - case '&': /* "&&" */ - if ((c = inputGetc(ep)) < 0 || c != '&') { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - tokenAddChar(ep, EJS_COND_AND); - return EJS_TOK_LOGICAL; - - case '\"': /* String quote */ - case '\'': - quote = c; - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, 0); - return EJS_TOK_ERR; - } - - while (c != quote) { - /* - * Check for escape sequence characters - */ - if (c == '\\') { - c = inputGetc(ep); - - if (isdigit(c)) { - /* - * Octal support, \101 maps to 65 = 'A'. Put first - * char back so converter will work properly. - */ - inputPutback(ep, c); - c = charConvert(ep, 8, 3); - - } else { - switch (c) { - case 'n': - c = '\n'; break; - case 'b': - c = '\b'; break; - case 'f': - c = '\f'; break; - case 'r': - c = '\r'; break; - case 't': - c = '\t'; break; - case 'x': - /* - * Hex support, \x41 maps to 65 = 'A' - */ - c = charConvert(ep, 16, 2); - break; - case 'u': - /* - * Unicode support, \x0401 maps to 65 = 'A' - */ - c = charConvert(ep, 16, 2); - c = c*16 + charConvert(ep, 16, 2); - - break; - case '\'': - case '\"': - case '\\': - break; - default: - if (tokenAddChar(ep, '\\') < 0) { - return EJS_TOK_ERR; - } - } - } - if (tokenAddChar(ep, c) < 0) { - return EJS_TOK_ERR; - } - } else { - if (tokenAddChar(ep, c) < 0) { - return EJS_TOK_ERR; - } - } - if ((c = inputGetc(ep)) < 0) { - ejsSyntaxError(ep, "Unmatched Quote"); - return EJS_TOK_ERR; - } - } - return EJS_TOK_LITERAL; - - case '0': - if (tokenAddChar(ep, c) < 0) { - return EJS_TOK_ERR; - } - if ((c = inputGetc(ep)) < 0) { - break; - } - if (tolower(c) == 'x') { - if (tokenAddChar(ep, c) < 0) { - return EJS_TOK_ERR; - } - if ((c = inputGetc(ep)) < 0) { - break; - } - isHex = 1; - if (! isxdigit(c)) { - parseNumber(ep, type); - inputPutback(ep, c); - return EJS_TOK_NUMBER; - } - } else if (! isdigit(c)) { -#if BLD_FEATURE_FLOATING_POINT - if (c == '.' || tolower(c) == 'e' || c == '+' || c == '-') { - /* Fall through */ - type = EJS_TYPE_FLOAT; - } else -#endif - { - parseNumber(ep, type); - inputPutback(ep, c); - return EJS_TOK_NUMBER; - } - } - /* Fall through to get more digits */ - - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (isHex) { - do { - if (tokenAddChar(ep, c) < 0) { - return EJS_TOK_ERR; - } - if ((c = inputGetc(ep)) < 0) { - break; - } - } while (isxdigit(c)); - - } else { -#if BLD_FEATURE_FLOATING_POINT - do { - if (tokenAddChar(ep, c) < 0) { - return EJS_TOK_ERR; - } - if ((c = inputGetc(ep)) < 0) { - break; - } - c = tolower(c); - if (c == '.' || c == 'e' || c == 'f') { - type = EJS_TYPE_FLOAT; - } - } while (isdigit(c) || c == '.' || c == 'e' || - c == 'f' || - ((type == EJS_TYPE_FLOAT) && (c == '+' || c == '-'))); -#else - do { - if (tokenAddChar(ep, c) < 0) { - return EJS_TOK_ERR; - } - if ((c = inputGetc(ep)) < 0) { - break; - } - } while (isdigit(c)); -#endif - } - - parseNumber(ep, type); - inputPutback(ep, c); - return EJS_TOK_NUMBER; - - default: - /* - * Identifiers or a function names - */ - while (1) { - if (c == '\\') { - if ((c = inputGetc(ep)) < 0) { - break; - } - if (c == '\n' || c == '\r') { - break; - } - } else if (tokenAddChar(ep, c) < 0) { - break; - } - if ((c = inputGetc(ep)) < 0) { - break; - } - if (!isalnum(c) && c != '$' && c != '_' && - c != '\\' && c != '@') { - break; - } - } - if (*ep->token == '\0') { - c = inputGetc(ep); - break; - } - - if (! isalpha((int) *ep->token) && *ep->token != '$' && - *ep->token != '_' && *ep->token != '@') { - ejsError(ep, EJS_SYNTAX_ERROR, "Invalid identifier %s", - ep->token); - return EJS_TOK_ERR; - } - - tid = checkReservedWord(ep, state, c, EJS_TOK_ID); - if (tid != EJS_TOK_ID) { - return tid; - } - - /* - * Skip white space after token to find out whether this is - * a function or not. - */ - while (c == ' ' || c == '\t' || c == '\r' || c == '\n') { - if ((c = inputGetc(ep)) < 0) - break; - } - - tid = EJS_TOK_ID; - if ((strlen(ep->token) + 1) >= EJS_MAX_ID) { - ejsError(ep, EJS_SYNTAX_ERROR, - "Identifier too big. Max is %d letters.", EJS_MAX_ID); - return EJS_TOK_ERR; - } - done++; - } - } - - /* - * Putback the last extra character for next time - */ - inputPutback(ep, c); - return tid; -} - -/******************************************************************************/ - -static void parseNumber(Ejs *ep, EjsType type) -{ - switch (type) { - case EJS_TYPE_INT: - ep->tokenNumber.integer = ejsParseInteger(ep->token); - ep->tokenNumber.type = type; - break; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - ep->tokenNumber.floating = atof(ep->token); - ep->tokenNumber.type = type; - break; -#endif - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - ep->tokenNumber.integer64 = ejsParseInteger64(ep->token); - ep->tokenNumber.type = type; - break; -#endif - } -} - -/******************************************************************************/ -/* - * Convert a hex or octal character back to binary, return original char if - * not a hex digit - */ - -static int charConvert(Ejs *ep, int base, int maxDig) -{ - int i, c, lval, convChar; - - lval = 0; - for (i = 0; i < maxDig; i++) { - if ((c = inputGetc(ep)) < 0) { - break; - } - /* - * Initialize to out of range value - */ - convChar = base; - if (isdigit(c)) { - convChar = c - '0'; - } else if (c >= 'a' && c <= 'f') { - convChar = c - 'a' + 10; - } else if (c >= 'A' && c <= 'F') { - convChar = c - 'A' + 10; - } - /* - * If unexpected character then return it to buffer. - */ - if (convChar >= base) { - inputPutback(ep, c); - break; - } - lval = (lval * base) + convChar; - } - return lval; -} - -/******************************************************************************/ -/* - * Putback the last token read. Accept at most one push back token. - */ - -void ejsLexPutbackToken(Ejs *ep, int tid, char *string) -{ - EjsInput *ip; - EjsToken *tp; - int idx; - - mprAssert(ep); - ip = ep->input; - mprAssert(ip); - - ip->putBackIndex += 1; - - mprAssert(ip->putBackIndex < EJS_TOKEN_STACK); - idx = ip->putBackIndex; - - tp = &ip->putBack[idx]; - tp->tid = tid; - - mprStrcpy(tp->tokbuf, sizeof(tp->tokbuf), string); -} - -/******************************************************************************/ -/* - * Add a character to the token buffer - */ - -static int tokenAddChar(Ejs *ep, int c) -{ - EjsInput *ip; - - mprAssert(ep); - ip = ep->input; - mprAssert(ip); - - if (ip->tokEndp >= &ip->tokbuf[sizeof(ip->tokbuf) - 1]) { - ejsSyntaxError(ep, "Token too big"); - return -1; - } - *ip->tokEndp++ = c; - *ip->tokEndp = '\0'; - - return 0; -} - -/******************************************************************************/ -/* - * Get another input character - */ - -static int inputGetc(Ejs *ep) -{ - EjsInput *ip; - int c; - - mprAssert(ep); - ip = ep->input; - - if (ip->scriptSize <= 0) { - return -1; - } - - c = (uchar) (*ip->scriptServp++); - ip->scriptSize--; - - /* - * For debugging, accumulate the line number and the currenly parsed line - */ - if (c == '\n') { -#if 0 && BLD_DEBUG - if (ip->lineColumn > 0) { - printf("PARSED: %s\n", ip->line); - } -#endif - ip->lineNumber++; - ip->lineColumn = 0; - } else if ((ip->lineColumn + 2) < sizeof(ip->line)) { - ip->line[ip->lineColumn++] = c; - ip->line[ip->lineColumn] = '\0'; - } - return c; -} - -/******************************************************************************/ -/* - * Putback a character onto the input queue - */ - -static void inputPutback(Ejs *ep, int c) -{ - EjsInput *ip; - - mprAssert(ep); - - if (c > 0) { - ip = ep->input; - *--ip->scriptServp = c; - ip->scriptSize++; - if (--(ip->lineColumn) < 0) { - ip->lineColumn = 0; - } - mprAssert(ip->line); - mprAssert(ip->lineColumn >= 0); - mprAssert(ip->lineColumn < sizeof(ip->line)); - ip->line[ip->lineColumn] = '\0'; - } -} - -/******************************************************************************/ - -#else -void ejsLexDummy() {} - -/******************************************************************************/ -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsParser.c b/source4/lib/appweb/ejs-2.0/ejs/ejsParser.c deleted file mode 100644 index 9fce6d27ee..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejsParser.c +++ /dev/null @@ -1,4514 +0,0 @@ -/* - * @file ejsParser.c - * @brief EJS Parser and Execution - */ -/********************************* Copyright **********************************/ -/* - * @copy default.g - * - * Copyright (c) Mbedthis Software LLC, 2003-2006. 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 "ejs.h" - -#if BLD_FEATURE_EJS - -/****************************** Forward Declarations **************************/ - -static int createClass(Ejs *ep, EjsVar *parentClass, - const char *className, EjsVar *baseClass); -static int createProperty(Ejs *ep, EjsVar **obj, const char *id, - int state); -static int evalCond(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs); -static int evalExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs); -#if BLD_FEATURE_FLOATING_POINT -static int evalFloatExpr(Ejs *ep, double l, int rel, double r); -#endif -static int evalBoolExpr(Ejs *ep, int l, int rel, int r); -static int evalNumericExpr(Ejs *ep, EjsNum l, int rel, EjsNum r); -static int evalObjExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs) ; -static int evalStringExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs); -static int evalMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, int flags); -static EjsProperty *findProperty(Ejs *ep, EjsVar *op, const char *property, - int flags); -static EjsVar *pickSpace(Ejs *ep, int state, const char *property, int flags); -static void freeProc(Ejs *ep, EjsProc *proc); -static int parseArgs(Ejs *ep, int state, int flags); -static int parseArrayLiteral(Ejs *ep, int state, int flags, char *id); -static int parseAssignment(Ejs *ep, int state, int flags, char *id); -static int parseClass(Ejs *ep, int state, int flags); -static int parseForInner(Ejs *ep, int state, int flags, - EjsInput *condScript, EjsInput *incrScript, - EjsInput *bodyScript, EjsInput *endScript); -static int parseCond(Ejs *ep, int state, int flags); -static int parseDeclaration(Ejs *ep, int state, int flags); -static int parseExpr(Ejs *ep, int state, int flags); -static int parseFor(Ejs *ep, int state, int flags); -static int parseRegFor(Ejs *ep, int state, int flags); -static int parseForIn(Ejs *ep, int state, int flags, int each); -static int parseId(Ejs *ep, int state, int flags, char **id, int *done); -static int parseInc(Ejs *ep, int state, int flags); -static int parseIf(Ejs *ep, int state, int flags, int *done); -static int parseFunction(Ejs *ep, int state, int flags); -static int parseMethod(Ejs *ep, int state, int flags, char *id); -static int parseObjectLiteral(Ejs *ep, int state, int flags, char *id); -static int parseStmt(Ejs *ep, int state, int flags); -static int parseThrow(Ejs *ep, int state, int flags); -static int parseTry(Ejs *ep, int state, int flags); -static void removeNewlines(Ejs *ep, int state); -static EjsProperty *searchSpacesForProperty(Ejs *ep, int state, EjsVar *obj, - char *property, int flags); -static int assignPropertyValue(Ejs *ep, char *id, int state, EjsVar *value, - int flags); -static int updateProperty(Ejs *ep, EjsVar *obj, const char *id, int state, - EjsVar *value); -static void updateResult(Ejs *ep, int state, int flags, EjsVar *vp); -static int getNextNonSpaceToken(Ejs *ep, int state); - -static int callConstructor(Ejs *ep, EjsVar *thisObj, EjsVar *baseClass, - MprArray *args); -static int callCMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, - EjsVar *prototype); -static int callStringCMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, - EjsVar *prototype); -static int callMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, - EjsVar *prototype); -static int runMethod(Ejs *ep, EjsVar *thisObj, EjsVar *method, - const char *methodName, MprArray *args); - -static EjsInput *getInputStruct(Ejs *ep); -static void freeInputStruct(Ejs *ep, EjsInput *input); - -static void *pushFrame(Ejs *ep, int size); -static void *popFrame(Ejs *ep, int size); - -/************************************* Code ***********************************/ -/* - * Recursive descent parser for EJS - */ - -int ejsParse(Ejs *ep, int state, int flags) -{ - mprAssert(ep); - -#if MOB - if (mprStackCheck(ep)) { - char *stack; - stack = ejsFormatStack(ep); - mprLog(ep, 0, "\nStack grew : MAX %d\n", mprStackSize(ep)); - mprLog(ep, 0, "Stack\n %s\n", stack); - mprFree(stack); - } -#endif - - if (ep->flags & EJS_FLAGS_EXIT) { - return EJS_STATE_RET; - } - - ep->inputMarker = ep->input->scriptServp; - - switch (state) { - /* - * Any statement, method arguments or conditional expressions - */ - case EJS_STATE_STMT: - state = parseStmt(ep, state, flags); - if (state != EJS_STATE_STMT_BLOCK_DONE && state != EJS_STATE_STMT_DONE){ - goto err; - } - break; - - case EJS_STATE_DEC: - state = parseStmt(ep, state, flags); - if (state != EJS_STATE_DEC_DONE) { - goto err; - } - break; - - case EJS_STATE_EXPR: - state = parseStmt(ep, state, flags); - if (state != EJS_STATE_EXPR_DONE) { - goto err; - } - break; - - /* - * Variable declaration list - */ - case EJS_STATE_DEC_LIST: - state = parseDeclaration(ep, state, flags); - if (state != EJS_STATE_DEC_LIST_DONE) { - goto err; - } - break; - - /* - * Method argument string - */ - case EJS_STATE_ARG_LIST: - state = parseArgs(ep, state, flags); - if (state != EJS_STATE_ARG_LIST_DONE) { - goto err; - } - break; - - /* - * Logical condition list (relational operations separated by &&, ||) - */ - case EJS_STATE_COND: - state = parseCond(ep, state, flags); - if (state != EJS_STATE_COND_DONE) { - goto err; - } - break; - - /* - * Expression list - */ - case EJS_STATE_RELEXP: - state = parseExpr(ep, state, flags); - if (state != EJS_STATE_RELEXP_DONE) { - goto err; - } - break; - } - - /* - * Recursion protection - */ - if (ep->input->scriptServp == ep->inputMarker) { - if (ep->recurseCount++ > 20) { - ejsSyntaxError(ep, "Input syntax error"); - state = EJS_STATE_ERR; - } - } else { - ep->recurseCount = 0; - } - - if (state == EJS_STATE_RET || state == EJS_STATE_EOF) { - return state; - } - -done: - return state; - -err: - if (state == EJS_STATE_RET || state == EJS_STATE_EOF) { - goto done; - } - if (state != EJS_STATE_ERR) { - ejsSyntaxError(ep, 0); - } - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct ParseStmt { - EjsProc *saveProc; - EjsProperty *pp; - EjsVar *saveObj, *exception; - char *str, *id; - int done, tid, rs, saveObjPerm, expectEndOfStmt; -} ParseStmt; - -/* - * Parse expression (leftHandSide operator rightHandSide) - */ - - -static int parseStmt(Ejs *ep, int state, int flags) -{ - ParseStmt *sp; - - mprAssert(ep); - - if ((sp = pushFrame(ep, sizeof(ParseStmt))) == 0) { - return EJS_STATE_ERR; - } - - sp->id = 0; - sp->expectEndOfStmt = 0; - sp->saveProc = NULL; - - ep->currentObj = 0; - ep->currentProperty = 0; - - for (sp->done = 0; !sp->done && state != EJS_STATE_ERR; ) { - sp->tid = ejsLexGetToken(ep, state); - -#if (WIN || BREW_SIMULATOR) && BLD_DEBUG && DISABLED - /* MOB -- make cross platform */ - _CrtCheckMemory(); -#endif - - switch (sp->tid) { - default: - ejsLexPutbackToken(ep, sp->tid, ep->token); - goto done; - - case EJS_TOK_EXPR: - if (state == EJS_STATE_EXPR) { - ejsLexPutbackToken(ep, EJS_TOK_EXPR, ep->token); - } - goto done; - - case EJS_TOK_LOGICAL: - ejsLexPutbackToken(ep, sp->tid, ep->token); - goto done; - - case EJS_TOK_ERR: - if (state != EJS_STATE_ERR && !ep->gotException) { - ejsSyntaxError(ep, 0); - } - state = EJS_STATE_ERR; - goto done; - - case EJS_TOK_EOF: - state = EJS_STATE_EOF; - goto done; - - case EJS_TOK_NEWLINE: - break; - - case EJS_TOK_SEMI: - /* - * This case is when we discover no statement and just a lone ';' - */ - if (state != EJS_STATE_STMT) { - ejsLexPutbackToken(ep, sp->tid, ep->token); - } - goto done; - - case EJS_TOK_LBRACKET: - if (flags & EJS_FLAGS_EXE) { - ep->currentObj = &ep->currentProperty->var; - if (ep->currentObj != 0 && ep->currentObj->type != - EJS_TYPE_OBJECT) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Property reference to a non-object type \"%s\"\n", - sp->id); - goto err; - } - } - - sp->saveObj = ep->currentObj; - sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1); - - sp->rs = ejsParse(ep, EJS_STATE_RELEXP, flags); - - ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm); - ep->currentObj = sp->saveObj; - - if (sp->rs < 0) { - state = sp->rs; - goto done; - } - - mprFree(sp->id); - /* MOB rc */ - sp->str = ejsVarToString(ep, ep->result); - sp->id = mprStrdup(ep, sp->str); - - if (sp->id[0] == '\0') { - if (flags & EJS_FLAGS_EXE) { - ejsError(ep, EJS_RANGE_ERROR, - "[] expression evaluates to the empty string\n"); - goto err; - } - } else { - sp->pp = searchSpacesForProperty(ep, state, ep->currentObj, - sp->id, flags); - ep->currentProperty = sp->pp; - updateResult(ep, state, flags, ejsGetVarPtr(sp->pp)); - } - - if ((sp->tid = ejsLexGetToken(ep, state)) != EJS_TOK_RBRACKET) { - ejsSyntaxError(ep, "Missing ']'"); - goto err; - } - break; - - case EJS_TOK_PERIOD: - if (flags & EJS_FLAGS_EXE) { - if (ep->currentProperty == 0) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Undefined object \"%s\"", sp->id); - goto err; - } - } - ep->currentObj = &ep->currentProperty->var; - if (flags & EJS_FLAGS_EXE) { - if (ep->currentObj != 0 && ep->currentObj->type != - EJS_TYPE_OBJECT) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Property reference to a non-object type \"%s\"\n", - sp->id); - goto err; - } - } - if ((sp->tid = ejsLexGetToken(ep, state)) != EJS_TOK_ID) { - ejsError(ep, EJS_REFERENCE_ERROR, "Bad property after '.': %s", - ep->token); - goto err; - } - /* Fall through */ - - case EJS_TOK_ID: - state = parseId(ep, state, flags, &sp->id, &sp->done); - if (sp->done && state == EJS_STATE_STMT) { - sp->expectEndOfStmt = 1; - } - break; - - case EJS_TOK_ASSIGNMENT: - sp->tid = ejsLexGetToken(ep, state); - if (sp->tid == EJS_TOK_LBRACE) { - /* - * var = { name: value, name: value, ... } - */ - if (parseObjectLiteral(ep, state, flags, sp->id) < 0) { - ejsSyntaxError(ep, "Bad object literal"); - goto err; - } - - } else if (sp->tid == EJS_TOK_LBRACKET) { - /* - * var = [ array elements ] - */ - if (parseArrayLiteral(ep, state, flags, sp->id) < 0) { - ejsSyntaxError(ep, "Bad array literal"); - goto err; - } - - } else if (sp->tid == EJS_TOK_EXPR && - (int) *ep->token == EJS_EXPR_LESS) { - /* - * var = <xmlTag> .../</xmlTag> - */ - ejsSyntaxError(ep, "XML literals are not yet supported"); - goto err; - - } else { - /* - * var = expression - */ - ejsLexPutbackToken(ep, sp->tid, ep->token); - state = parseAssignment(ep, state, flags, sp->id); - if (state == EJS_STATE_ERR) { - if (ep->flags & EJS_FLAGS_EXIT) { - state = EJS_STATE_RET; - goto done; - } - if (!ep->gotException) { - ejsSyntaxError(ep, 0); - } - goto err; - } - } - - if (flags & EJS_FLAGS_EXE) { - if (assignPropertyValue(ep, sp->id, state, ep->result, - flags) < 0) { - if (ep->gotException == 0) { - ejsError(ep, EJS_EVAL_ERROR, "Can't set property %s", - sp->id); - } - goto err; - } - } - - if (state == EJS_STATE_STMT) { - sp->expectEndOfStmt = 1; - goto done; - } - break; - - case EJS_TOK_INC_DEC: - state = parseInc(ep, state, flags); - if (state == EJS_STATE_STMT) { - sp->expectEndOfStmt = 1; - } - break; - - case EJS_TOK_NEW: - /* MOB -- could we remove rs and just use state */ - sp->rs = ejsParse(ep, EJS_STATE_EXPR, flags | EJS_FLAGS_NEW); - if (sp->rs < 0) { - state = sp->rs; - goto done; - } - break; - - case EJS_TOK_DELETE: - sp->rs = ejsParse(ep, EJS_STATE_EXPR, flags | EJS_FLAGS_DELETE); - if (sp->rs < 0) { - state = sp->rs; - goto done; - } - if (flags & EJS_FLAGS_EXE) { - /* Single place where properties are deleted */ - if (ep->currentObj == 0 || ep->currentProperty == 0) { - ejsError(ep, EJS_EVAL_ERROR, - "Can't find property to delete"); - goto err; - } - if (ep->currentObj->isArray) { - ejsSetArrayLength(ep, ep->currentObj, 0, - ep->currentProperty->name, 0); - } - ejsDeleteProperty(ep, ep->currentObj, - ep->currentProperty->name); - ep->currentProperty = 0; - } - goto done; - - case EJS_TOK_FUNCTION: - /* - * Parse a function declaration - */ - state = parseFunction(ep, state, flags); - goto done; - - case EJS_TOK_THROW: - state = parseThrow(ep, state, flags); - goto done; - - case EJS_TOK_TRY: - state = parseTry(ep, state, flags); - goto done; - - case EJS_TOK_CLASS: - case EJS_TOK_MODULE: - state = parseClass(ep, state, flags); - goto done; - - case EJS_TOK_LITERAL: - /* - * Set the result to the string literal - */ - if (flags & EJS_FLAGS_EXE) { - ejsWriteVarAsString(ep, ep->result, ep->token); - ejsSetVarName(ep, ep->result, ""); - } - if (state == EJS_STATE_STMT) { - sp->expectEndOfStmt = 1; - } - goto done; - - case EJS_TOK_NUMBER: - /* - * Set the result to the parsed number - */ - if (flags & EJS_FLAGS_EXE) { - ejsWriteVar(ep, ep->result, &ep->tokenNumber, 0); - } - if (state == EJS_STATE_STMT) { - sp->expectEndOfStmt = 1; - } - goto done; - - case EJS_TOK_METHOD_NAME: - /* - * parse a method() invocation - */ - mprAssert(ep->currentObj); - state = parseMethod(ep, state, flags, sp->id); - if (state == EJS_STATE_STMT) { - sp->expectEndOfStmt = 1; - } - if (ep->flags & EJS_FLAGS_EXIT) { - state = EJS_STATE_RET; - } - goto done; - - case EJS_TOK_IF: - state = parseIf(ep, state, flags, &sp->done); - if (state < 0) { - goto done; - } - break; - - case EJS_TOK_FOR: - state = parseFor(ep, state, flags); - goto done; - - case EJS_TOK_VAR: - if ((sp->rs = ejsParse(ep, EJS_STATE_DEC_LIST, flags)) < 0) { - state = sp->rs; - goto done; - } - goto done; - - case EJS_TOK_COMMA: - ejsLexPutbackToken(ep, sp->tid, ep->token); - goto done; - - case EJS_TOK_LPAREN: - if (state == EJS_STATE_EXPR) { - if ((sp->rs = ejsParse(ep, EJS_STATE_RELEXP, flags)) < 0) { - state = sp->rs; - goto done; - } - if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) { - ejsSyntaxError(ep, 0); - goto err; - } - goto done; - - } else if (state == EJS_STATE_STMT) { - ejsLexPutbackToken(ep, EJS_TOK_METHOD_NAME, ep->token); - } - break; - - case EJS_TOK_RPAREN: - ejsLexPutbackToken(ep, sp->tid, ep->token); - goto done; - - case EJS_TOK_EXTENDS: - if (! (flags & EJS_FLAGS_CLASS_DEC)) { - ejsSyntaxError(ep, 0); - goto err; - } - sp->saveObj = ep->currentObj; - sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1); - - sp->rs = ejsParse(ep, EJS_STATE_STMT, flags); - ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm); - - if (sp->rs < 0) { - state = sp->rs; - goto done; - } - - if (flags & EJS_FLAGS_EXE) { - if (createClass(ep, sp->saveObj, sp->id, - ejsGetVarPtr(ep->currentProperty)) < 0) { - goto err; - } - } - if (ejsLexGetToken(ep, state) != EJS_TOK_LBRACE) { - ejsSyntaxError(ep, 0); - goto err; - } - ejsLexPutbackToken(ep, ep->tid, ep->token); - goto done; - - case EJS_TOK_LBRACE: - if (flags & EJS_FLAGS_CLASS_DEC) { - if (state == EJS_STATE_DEC) { - if (flags & EJS_FLAGS_EXE) { - if (createClass(ep, ep->currentObj, sp->id, 0) < 0) { - goto err; - } - } - ejsLexPutbackToken(ep, sp->tid, ep->token); - - } else if (state == EJS_STATE_STMT) { - ejsLexPutbackToken(ep, sp->tid, ep->token); - } - goto done; - } - - /* - * This handles any code in braces except "if () {} else {}" - */ - if (state != EJS_STATE_STMT) { - ejsSyntaxError(ep, 0); - goto err; - } - - /* - * Parse will return EJS_STATE_STMT_BLOCK_DONE when the RBRACE - * is seen. - */ - sp->exception = 0; - do { - state = ejsParse(ep, EJS_STATE_STMT, flags); - if (state == EJS_STATE_ERR) { - /* - * We need to keep parsing to get to the end of the block - */ - if (sp->exception == 0) { - sp->exception = ejsDupVar(ep, ep->result, - EJS_SHALLOW_COPY); - if (sp->exception == 0) { - ejsMemoryError(ep); - goto err; - } - if (sp->exception->type == EJS_TYPE_OBJECT) { - ejsMakeObjLive(sp->exception, 0); - mprAssert(sp->exception->objectState->alive == 0); - } - - /* - * If we're in a try block, we need to keep parsing - * so we can find the end of the block and the start - * of the catch block. Otherwise, we are done. - */ - if (!(flags & EJS_FLAGS_TRY)) { - break; - } - } - flags &= ~EJS_FLAGS_EXE; - if (ep->recurseCount > 20) { - break; - } - state = EJS_STATE_STMT_DONE; - ep->gotException = 0; - } - - } while (state == EJS_STATE_STMT_DONE); - - if (sp->exception) { - ep->gotException = 1; - ejsWriteVar(ep, ep->result, sp->exception, EJS_SHALLOW_COPY); - - /* Eat the closing brace */ - ejsLexGetToken(ep, state); - ejsFreeVar(ep, sp->exception); - - goto err; - } - ejsFreeVar(ep, sp->exception); - - if (state < 0) { - goto done; - } - - if (ejsLexGetToken(ep, state) != EJS_TOK_RBRACE) { - ejsSyntaxError(ep, 0); - goto err; - } - state = EJS_STATE_STMT_DONE; - goto done; - - case EJS_TOK_RBRACE: - if (state == EJS_STATE_STMT) { - ejsLexPutbackToken(ep, sp->tid, ep->token); - state = EJS_STATE_STMT_BLOCK_DONE; - - } else if (state == EJS_STATE_EXPR) { - ejsLexPutbackToken(ep, sp->tid, ep->token); - state = EJS_STATE_EXPR; - - } else { - ejsSyntaxError(ep, 0); - state = EJS_STATE_ERR; - } - goto done; - - case EJS_TOK_RETURN: - if ((sp->rs = ejsParse(ep, EJS_STATE_RELEXP, flags)) < 0) { - state = sp->rs; - goto done; - } - if (flags & EJS_FLAGS_EXE) { - state = EJS_STATE_RET; - goto done; - } - break; - } - } -done: - mprFree(sp->id); - - if (sp->expectEndOfStmt && state >= 0) { - sp->tid = ejsLexGetToken(ep, state); - if (sp->tid == EJS_TOK_RBRACE) { - ejsLexPutbackToken(ep, EJS_TOK_RBRACE, ep->token); - - } else if (sp->tid != EJS_TOK_SEMI && sp->tid != EJS_TOK_NEWLINE && - sp->tid != EJS_TOK_EOF) { - ejsSyntaxError(ep, 0); - state = EJS_STATE_ERR; - - } else { - /* - * Skip newlines after semi-colon - */ - removeNewlines(ep, state); - } - } - - /* - * Advance the state - */ - switch (state) { - case EJS_STATE_STMT: - case EJS_STATE_STMT_DONE: - state = EJS_STATE_STMT_DONE; - break; - - case EJS_STATE_DEC: - case EJS_STATE_DEC_DONE: - state = EJS_STATE_DEC_DONE; - break; - - case EJS_STATE_EXPR: - case EJS_STATE_EXPR_DONE: - state = EJS_STATE_EXPR_DONE; - break; - - case EJS_STATE_STMT_BLOCK_DONE: - case EJS_STATE_EOF: - case EJS_STATE_RET: - break; - - default: - if (state != EJS_STATE_ERR) { - ejsSyntaxError(ep, 0); - } - state = EJS_STATE_ERR; - } - popFrame(ep, sizeof(ParseStmt)); - return state; - -err: - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct ParseFor { - char *initToken; - int tid, foundVar, initId, each; -} ParseFor; - -/* - * Parse method arguments - */ - -static int parseFor(Ejs *ep, int state, int flags) -{ - ParseFor *sp; - - if ((sp = pushFrame(ep, sizeof(ParseFor))) == 0) { - return EJS_STATE_ERR; - } - - mprAssert(ep); - - if (state != EJS_STATE_STMT) { - ejsSyntaxError(ep, 0); - goto err; - } - - if ((sp->tid = ejsLexGetToken(ep, state)) == EJS_TOK_EACH) { - sp->each = 1; - sp->tid = ejsLexGetToken(ep, state); - - } else { - sp->each = 0; - } - - if (sp->tid != EJS_TOK_LPAREN) { - ejsSyntaxError(ep, 0); - goto err; - } - - /* - * Need to peek 2-3 tokens ahead and see if this is a - * for [each] ([var] x in set) - * or - * for (init ; whileCond; incr) - */ - sp->initId = ejsLexGetToken(ep, EJS_STATE_EXPR); - sp->foundVar = 0; - if (sp->initId == EJS_TOK_ID && strcmp(ep->token, "var") == 0) { - sp->foundVar = 1; - sp->initId = ejsLexGetToken(ep, EJS_STATE_EXPR); - } - sp->initToken = mprStrdup(ep, ep->token); - - sp->tid = ejsLexGetToken(ep, EJS_STATE_EXPR); - - ejsLexPutbackToken(ep, sp->tid, ep->token); - ejsLexPutbackToken(ep, sp->initId, sp->initToken); - mprFree(sp->initToken); - - if (sp->foundVar) { - ejsLexPutbackToken(ep, EJS_TOK_ID, "var"); - } - - if (sp->tid == EJS_TOK_IN) { - state = parseForIn(ep, state, flags, sp->each); - - } else { - state = parseRegFor(ep, state, flags); - } - -done: - popFrame(ep, sizeof(ParseFor)); - return state; - -err: - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Parse method arguments - */ - -static int parseArgs(Ejs *ep, int state, int flags) -{ - EjsVar *vp; - int tid; - - mprAssert(ep); - - do { - /* - * Peek and see if there are no args - */ - tid = ejsLexGetToken(ep, state); - ejsLexPutbackToken(ep, tid, ep->token); - if (tid == EJS_TOK_RPAREN) { - break; - } - - /* - * If this is part of a constructor, must run methods in args normally - */ - flags &= ~EJS_FLAGS_NEW; - - state = ejsParse(ep, EJS_STATE_RELEXP, flags); - if (state < 0) { - return state; - } - if (flags & EJS_FLAGS_EXE) { - mprAssert(ep->proc->args); - vp = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY); - if (vp == 0) { - ejsMemoryError(ep); - return EJS_STATE_ERR; - } - /* MOB */ - if (vp->type == EJS_TYPE_OBJECT) { - ejsMakeObjLive(vp, 0); - mprAssert(vp->objectState->alive == 0); - } - - /* - * Propagate the name - */ - ejsSetVarName(ep, vp, ep->result->propertyName); - - mprAddItem(ep->proc->args, vp); - - } - /* - * Peek at the next token, continue if more args (ie. comma seen) - */ - tid = ejsLexGetToken(ep, state); - if (tid != EJS_TOK_COMMA) { - ejsLexPutbackToken(ep, tid, ep->token); - } - } while (tid == EJS_TOK_COMMA); - - if (tid != EJS_TOK_RPAREN && state != EJS_STATE_RELEXP_DONE) { - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - return EJS_STATE_ARG_LIST_DONE; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct ParseAssign { - EjsProperty *saveProperty; - EjsVar *saveObj; - int saveObjPerm, savePropPerm, rc; -} ParseAssign; - -/* - * Parse an assignment statement - */ - -static int parseAssignment(Ejs *ep, int state, int flags, char *id) -{ - ParseAssign *sp; - - - if (id == 0) { - if (!ep->gotException) { - ejsSyntaxError(ep, 0); - } - return EJS_STATE_ERR; - } - - if ((sp = pushFrame(ep, sizeof(ParseAssign))) == 0) { - return EJS_STATE_ERR; - } - - mprAssert(ep->currentObj); - - /* - * Parse the right hand side of the "=" - */ - sp->saveObj = ep->currentObj; - sp->saveProperty = ep->currentProperty; - - sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1); - sp->savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(sp->saveProperty), 1); - - sp->rc = ejsParse(ep, EJS_STATE_RELEXP, flags | EJS_FLAGS_ASSIGNMENT); - - ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm); - ejsMakeObjPermanent(ejsGetVarPtr(sp->saveProperty), sp->savePropPerm); - - if (sp->rc < 0) { - state = EJS_STATE_ERR; - } - - ep->currentObj = sp->saveObj; - ep->currentProperty = sp->saveProperty; - - popFrame(ep, sizeof(ParseAssign)); - - if (! (flags & EJS_FLAGS_EXE)) { - return state; - } - - return state; -} - -/******************************************************************************/ - -static int assignPropertyValue(Ejs *ep, char *id, int state, EjsVar *value, - int flags) -{ - EjsProperty *saveProperty; - EjsVar *saveObj, *obj, *vp; - char *procName; - int saveObjPerm, savePropPerm, rc; - - mprAssert(flags & EJS_FLAGS_EXE); - - if (ep->currentProperty && - !ep->currentProperty->var.flags & EJS_GET_ACCESSOR) { - obj = ep->currentObj; - - } else { - /* - * Handle any set accessors. - * FUTURE OPT -- could be faster - * FUTURE OPT -- coming here even when doing just a set "x = value"; - */ - procName = 0; - if (mprAllocStrcat(MPR_LOC_ARGS(ep), &procName, EJS_MAX_ID + 5, 0, - "-set-", id, 0) > 0) { - - MprArray *args; - - ep->currentProperty = searchSpacesForProperty(ep, state, - ep->currentObj, procName, flags); - - if (ep->currentProperty) { - args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); - - vp = ejsDupVar(ep, value, EJS_SHALLOW_COPY); - mprAddItem(args, vp); - mprAssert(! ejsObjIsCollectable(vp)); - - saveObj = ep->currentObj; - saveProperty = ep->currentProperty; - - saveObjPerm = ejsMakeObjPermanent(saveObj, 1); - savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), - 1); - - /* - * Invoke the set accessor - */ - rc = ejsRunMethod(ep, ep->currentObj, procName, args); - mprFree(procName); - ejsFreeMethodArgs(ep, args); - - ejsMakeObjPermanent(saveObj, saveObjPerm); - ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm); - - ep->currentObj = saveObj; - ep->currentProperty = saveProperty; - - if (rc < 0) { - return EJS_STATE_ERR; - } - return state; - } - mprFree(procName); - } - - if (ep->currentProperty == 0) { - /* - * MOB -- can we omit this as updateProperty below will create - */ - if (createProperty(ep, &obj, id, state) < 0) { - return EJS_STATE_ERR; - } - } - } - - if (updateProperty(ep, obj, id, state, value) < 0) { - return EJS_STATE_ERR; - } - - vp = ejsGetVarPtr(ep->currentProperty); - if (vp->type == EJS_TYPE_OBJECT) { - ejsMakeObjLive(vp, 1); - } - - return state; -} - -/******************************************************************************/ - -static int parseObjectLiteral(Ejs *ep, int state, int flags, char *id) -{ - EjsProperty *saveProperty; - EjsVar *saveObj; - EjsVar *obj; - char *name; - int saveObjPerm, savePropPerm, tid; - - name = 0; - - saveObj = ep->currentObj; - saveProperty = ep->currentProperty; - - saveObjPerm = ejsMakeObjPermanent(saveObj, 1); - savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), 1); - - if (flags & EJS_FLAGS_EXE) { - obj = ejsCreateSimpleObj(ep, "Object"); - if (obj == 0) { - ejsMemoryError(ep); - goto err; - } - mprAssert(! ejsObjIsCollectable(obj)); - - } else { - obj = 0; - } - - do { - tid = getNextNonSpaceToken(ep, state); - if (tid != EJS_TOK_ID) { - ejsSyntaxError(ep, 0); - goto err; - } - name = mprStrdup(ep, ep->token); - - tid = getNextNonSpaceToken(ep, state); - if (tid != EJS_TOK_COLON) { - ejsSyntaxError(ep, 0); - goto err; - } - - if (flags & EJS_FLAGS_EXE) { - /* FUTURE OPT -- can we optimize this. We are double accessing id - with the Put below. Should we be using this or ejsSetProperty - */ - if (ejsCreatePropertyMethod(ep, obj, name) == 0) { - ejsMemoryError(ep); - goto err; - } - } - - if (ejsParse(ep, EJS_STATE_RELEXP, flags) < 0) { - goto err; - } - if (flags & EJS_FLAGS_EXE) { - if (ejsSetPropertyMethod(ep, obj, name, ep->result) == 0) { - ejsMemoryError(ep); - goto err; - } - } - mprFree(name); - name = 0; - - tid = getNextNonSpaceToken(ep, state); - - } while (tid == EJS_TOK_COMMA); - - if (tid != EJS_TOK_RBRACE) { - ejsSyntaxError(ep, 0); - goto err; - } - - if (flags & EJS_FLAGS_EXE) { - ejsMakeObjLive(obj, 1); - ejsWriteVar(ep, ep->result, obj, EJS_SHALLOW_COPY); - } - -done: - ejsMakeObjPermanent(saveObj, saveObjPerm); - ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm); - - ep->currentObj = saveObj; - ep->currentProperty = saveProperty; - - if (obj) { - ejsFreeVar(ep, obj); - } - return state; - -err: - mprFree(name); - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ - -static int parseArrayLiteral(Ejs *ep, int state, int flags, char *id) -{ - EjsProperty *saveProperty; - EjsVar *saveObj; - EjsVar *obj; - int saveObjPerm, savePropPerm, tid; - - saveObj = ep->currentObj; - saveProperty = ep->currentProperty; - - saveObjPerm = ejsMakeObjPermanent(saveObj, 1); - savePropPerm = ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), 1); - - if (flags & EJS_FLAGS_EXE) { - obj = ejsCreateArray(ep, 0); - if (obj == 0) { - ejsMemoryError(ep); - goto err; - } - mprAssert(! ejsObjIsCollectable(obj)); - - } else { - obj = 0; - } - - do { - if (ejsParse(ep, EJS_STATE_RELEXP, flags) < 0) { - goto err; - } - if (flags & EJS_FLAGS_EXE) { - /* MOB _- should this be put[array.length] */ - if (ejsAddArrayElt(ep, obj, ep->result, EJS_SHALLOW_COPY) == 0) { - goto err; - } - } - - tid = getNextNonSpaceToken(ep, state); - - } while (tid == EJS_TOK_COMMA); - - if (tid != EJS_TOK_RBRACKET) { - ejsSyntaxError(ep, "Missing right bracket"); - goto err; - } - - if (flags & EJS_FLAGS_EXE) { - ejsMakeObjLive(obj, 1); - ejsWriteVar(ep, ep->result, obj, EJS_SHALLOW_COPY); - } - -done: - ejsMakeObjPermanent(saveObj, saveObjPerm); - ejsMakeObjPermanent(ejsGetVarPtr(saveProperty), savePropPerm); - - ep->currentObj = saveObj; - ep->currentProperty = saveProperty; - - ejsFreeVar(ep, obj); - return state; - -err: - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Create a property. - */ - -/* -MOB -- simplify this. Enforce ep->currentObj to be always set. -Then we can delete this and just call - - ejsCreatePropertyMethod(ep->currentObj, id); -*/ -//XX -static int createProperty(Ejs *ep, EjsVar **objp, const char *id, int state) -{ - EjsVar *obj, *vp; - - mprAssert(id && *id); - mprAssert(objp); - - /* - * Determine the variable scope to use for the property. - * Standard says: "var x" means declare locally. - * "x = 2" means declare globally if x is undefined. - */ - if (ep->currentObj) { - if (ep->currentObj->type != EJS_TYPE_OBJECT) { - ejsSyntaxError(ep, "Reference is not an object"); - return EJS_STATE_ERR; - } - obj = ep->currentObj; - - } else { - /* MOB -- we should never be doing this here. ep->currentObj should - always be set already */ - obj = (state == EJS_STATE_DEC) ? ep->local : ep->global; - } - mprAssert(obj); - - vp = ejsCreatePropertyMethod(ep, obj, id); - if (vp == 0) { - if (!ep->gotException) { - ejsMemoryError(ep); - } - return EJS_STATE_ERR; - } - - *objp = obj; - return state; -} - -/******************************************************************************/ -/* - * Update a property. - * - * Return with ep->currentProperty updated to point to the property. - */ - -static int updateProperty(Ejs *ep, EjsVar *obj, const char *id, int state, - EjsVar *value) -{ - EjsVar *vp; - - /* - * MOB -- do ready-only check here - */ - vp = ejsSetPropertyMethod(ep, obj, id, value); - if (vp == 0) { - ejsMemoryError(ep); - return EJS_STATE_ERR; - } - ep->currentProperty = ejsGetPropertyPtr(vp); - - obj->objectState->dirty = 1; - - return state; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct ParseCond { - EjsVar lhs, rhs; - int tid, operator; -} ParseCond; - -/* - * Parse conditional expression (relational ops separated by ||, &&) - */ - -static int parseCond(Ejs *ep, int state, int flags) -{ - ParseCond *sp; - - if ((sp = pushFrame(ep, sizeof(ParseCond))) == 0) { - return EJS_STATE_ERR; - } - - mprAssert(ep); - - if (flags & EJS_FLAGS_EXE) { - ejsClearVar(ep, ep->result); - } - - sp->lhs.type = sp->rhs.type = EJS_TYPE_UNDEFINED; - sp->lhs.objectState = sp->rhs.objectState = 0; - sp->lhs.allocatedData = sp->rhs.allocatedData = 0; - - ejsSetVarName(ep, &sp->lhs, "lhs"); - ejsSetVarName(ep, &sp->rhs, "rhs"); - - sp->operator = 0; - - do { - /* - * Recurse to handle one side of a conditional. Accumulate the - * left hand side and the final result in ep->result. - */ - state = ejsParse(ep, EJS_STATE_RELEXP, flags); - if (state < 0) { - break; - } - - if (flags & EJS_FLAGS_EXE) { - if (sp->operator > 0) { - /* - * FUTURE -- does not do precedence - */ - ejsWriteVar(ep, &sp->rhs, ep->result, EJS_SHALLOW_COPY); - if (evalCond(ep, &sp->lhs, sp->operator, &sp->rhs) < 0) { - state = EJS_STATE_ERR; - break; - } - /* Result left in ep->result */ - /* MOB */ - if (sp->lhs.type == EJS_TYPE_OBJECT) { - mprAssert(sp->lhs.objectState->alive == 0); - } - if (sp->rhs.type == EJS_TYPE_OBJECT) { - mprAssert(sp->rhs.objectState->alive == 0); - } - } - } - - sp->tid = ejsLexGetToken(ep, state); - if (sp->tid == EJS_TOK_LOGICAL) { - sp->operator = (int) *ep->token; - - } else if (sp->tid == EJS_TOK_RPAREN || sp->tid == EJS_TOK_SEMI) { - ejsLexPutbackToken(ep, sp->tid, ep->token); - state = EJS_STATE_COND_DONE; - break; - - } else { - ejsLexPutbackToken(ep, sp->tid, ep->token); - } - - if (flags & EJS_FLAGS_EXE) { - ejsWriteVar(ep, &sp->lhs, ep->result, EJS_SHALLOW_COPY); - } - - } while (state == EJS_STATE_RELEXP_DONE); - - ejsClearVar(ep, &sp->lhs); - ejsClearVar(ep, &sp->rhs); - - popFrame(ep, sizeof(ParseCond)); - - return state; -} - -/******************************************************************************/ -/* - * Parse variable declaration list. Declarations can be of the following forms: - * var x; - * var x, y, z; - * var x = 1 + 2 / 3, y = 2 + 4; - * var x = { property: value, property: value ... }; - * var x = [ property: value, property: value ... ]; - * - * We set the variable to NULL if there is no associated assignment. - */ - -static int parseDeclaration(Ejs *ep, int state, int flags) -{ - int tid; - - mprAssert(ep); - - do { - if ((tid = ejsLexGetToken(ep, state)) != EJS_TOK_ID) { - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - ejsLexPutbackToken(ep, tid, ep->token); - - /* - * Parse the entire assignment or simple identifier declaration - */ - if (ejsParse(ep, EJS_STATE_DEC, flags) != EJS_STATE_DEC_DONE) { - return EJS_STATE_ERR; - } - - /* - * Peek at the next token, continue if comma seen - * Stop on ";" or "in" which is used in a "for (var x in ..." - */ - tid = ejsLexGetToken(ep, state); - - if (tid == EJS_TOK_SEMI) { - return EJS_STATE_DEC_LIST_DONE; - - } else if (tid == EJS_TOK_IN) { - ejsLexPutbackToken(ep, tid, ep->token); - return EJS_STATE_DEC_LIST_DONE; - - } else if (flags & EJS_FLAGS_CLASS_DEC && - (tid == EJS_TOK_LBRACE || tid == EJS_TOK_EXTENDS)) { - ejsLexPutbackToken(ep, tid, ep->token); - return EJS_STATE_DEC_LIST_DONE; - - } else if (tid == EJS_TOK_RPAREN && flags & EJS_FLAGS_CATCH) { - ejsLexPutbackToken(ep, tid, ep->token); - return EJS_STATE_DEC_LIST_DONE; - - } else if (tid != EJS_TOK_COMMA) { - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - - } while (tid == EJS_TOK_COMMA); - - if (tid != EJS_TOK_SEMI) { - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - return EJS_STATE_DEC_LIST_DONE; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct ParseExpr { - EjsVar lhs, rhs; - int rel, tid, unaryMinus; -} ParseExpr; - -/* - * Parse expression (leftHandSide operator rightHandSide) - */ - -static int parseExpr(Ejs *ep, int state, int flags) -{ - ParseExpr *sp; - - mprAssert(ep); - - if ((sp = pushFrame(ep, sizeof(ParseExpr))) == 0) { - return EJS_STATE_ERR; - } - - if (flags & EJS_FLAGS_EXE) { - ejsClearVar(ep, ep->result); - } - - sp->lhs.type = sp->rhs.type = EJS_TYPE_UNDEFINED; - sp->lhs.objectState = sp->rhs.objectState = 0; - sp->lhs.allocatedData = sp->rhs.allocatedData = 0; - - ejsSetVarName(ep, &sp->lhs, "lhs"); - ejsSetVarName(ep, &sp->rhs, "rhs"); - - sp->rel = 0; - sp->tid = 0; - sp->unaryMinus = 0; - - do { - /* - * This loop will handle an entire expression list. We call parse - * to evalutate each term which returns the result in ep->result. - */ - if (sp->tid == EJS_TOK_LOGICAL) { - state = ejsParse(ep, EJS_STATE_RELEXP, flags); - if (state < 0) { - break; - } - } else { - sp->tid = ejsLexGetToken(ep, state); - if (sp->tid == EJS_TOK_EXPR && (int) *ep->token == EJS_EXPR_MINUS) { - sp->unaryMinus = 1; - - } else { - ejsLexPutbackToken(ep, sp->tid, ep->token); - } - - state = ejsParse(ep, EJS_STATE_EXPR, flags); - if (state < 0) { - break; - } - } - - if (flags & EJS_FLAGS_EXE) { - if (sp->unaryMinus) { - switch (ep->result->type) { - default: - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - case EJS_TYPE_STRING_CMETHOD: - case EJS_TYPE_CMETHOD: - case EJS_TYPE_METHOD: - case EJS_TYPE_PTR: - case EJS_TYPE_OBJECT: - case EJS_TYPE_STRING: - case EJS_TYPE_BOOL: - ejsError(ep, EJS_SYNTAX_ERROR, "Invalid unary minus"); - state = EJS_STATE_ERR; - break; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - ep->result->floating = - ep->result->floating; - break; -#endif - - case EJS_TYPE_INT: - ep->result->integer = - ep->result->integer; - break; - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - ep->result->integer64 = - ep->result->integer64; - break; -#endif - } - } - sp->unaryMinus = 0; - - if (sp->rel > 0) { - ejsWriteVar(ep, &sp->rhs, ep->result, EJS_SHALLOW_COPY); - if (sp->tid == EJS_TOK_LOGICAL) { - if (evalCond(ep, &sp->lhs, sp->rel, &sp->rhs) < 0) { - state = EJS_STATE_ERR; - break; - } - } else { - if (evalExpr(ep, &sp->lhs, sp->rel, &sp->rhs) < 0) { - state = EJS_STATE_ERR; - break; - } - } - } - /* MOB */ - if (sp->lhs.type == EJS_TYPE_OBJECT) { - ejsMakeObjLive(&sp->lhs, 0); - mprAssert(sp->lhs.objectState->alive == 0); - } - if (sp->rhs.type == EJS_TYPE_OBJECT) { - ejsMakeObjLive(&sp->rhs, 0); - mprAssert(sp->rhs.objectState->alive == 0); - } - } - - if ((sp->tid = ejsLexGetToken(ep, state)) == EJS_TOK_EXPR || - sp->tid == EJS_TOK_INC_DEC || sp->tid == EJS_TOK_LOGICAL) { - sp->rel = (int) *ep->token; - ejsWriteVar(ep, &sp->lhs, ep->result, EJS_SHALLOW_COPY); - - } else { - ejsLexPutbackToken(ep, sp->tid, ep->token); - state = EJS_STATE_RELEXP_DONE; - } - - } while (state == EJS_STATE_EXPR_DONE); - - ejsClearVar(ep, &sp->lhs); - ejsClearVar(ep, &sp->rhs); - - popFrame(ep, sizeof(ParseExpr)); - - return state; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct ParseForIn { - EjsInput *endScript, *bodyScript; - EjsProperty *pp, *nextp; - EjsVar *iteratorVar, *setVar, *vp; - int forFlags, tid; -} ParseForIn; - -/* - * Parse the "for ... in" statement. Format for the statement is: - * - * for [each] (var varName in expression) { - * body; - * } - */ - -static int parseForIn(Ejs *ep, int state, int flags, int each) -{ - ParseForIn *sp; - - mprAssert(ep); - - if ((sp = pushFrame(ep, sizeof(ParseForIn))) == 0) { - return EJS_STATE_ERR; - } - - sp->setVar = 0; - sp->iteratorVar = 0; - sp->bodyScript = 0; - sp->endScript = 0; - - sp->tid = ejsLexGetToken(ep, state); - if (sp->tid != EJS_TOK_ID && sp->tid != EJS_TOK_VAR) { - ejsSyntaxError(ep, 0); - goto err; - } - ejsLexPutbackToken(ep, sp->tid, ep->token); - - state = ejsParse(ep, EJS_STATE_EXPR, EJS_FLAGS_FORIN | flags); - if (state < 0) { - goto done; - } - if (flags & EJS_FLAGS_EXE) { - if (ep->currentProperty == 0) { - ejsSyntaxError(ep, 0); - goto err; - } - sp->iteratorVar = &ep->currentProperty->var; - } else { - sp->iteratorVar = 0; - } - - if (ejsLexGetToken(ep, state) != EJS_TOK_IN) { - ejsSyntaxError(ep, 0); - goto err; - } - - /* - * Get the set - */ - sp->tid = ejsLexGetToken(ep, state); - if (sp->tid != EJS_TOK_ID) { - ejsSyntaxError(ep, 0); - goto err; - } - ejsLexPutbackToken(ep, sp->tid, ep->token); - - state = ejsParse(ep, EJS_STATE_EXPR, flags); - if (state < 0) { - goto done; - } - - if ((flags & EJS_FLAGS_EXE) && - (ep->result == 0 || ep->result->type == EJS_TYPE_UNDEFINED)) { - ejsError(ep, EJS_REFERENCE_ERROR, "Can't access array or object"); - goto err; - } - - if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) { - ejsSyntaxError(ep, 0); - goto err; - } - - sp->setVar = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY); - - sp->bodyScript = getInputStruct(ep); - - /* - * Parse the body and remember the end of the body script - */ - sp->forFlags = flags & ~EJS_FLAGS_EXE; - ejsLexSaveInputState(ep, sp->bodyScript); - - state = ejsParse(ep, EJS_STATE_STMT, sp->forFlags); - if (state < 0) { - goto done; - } - - sp->endScript = getInputStruct(ep); - ejsInitInputState(sp->endScript); - ejsLexSaveInputState(ep, sp->endScript); - - /* - * Enumerate the properties - */ - if (flags & EJS_FLAGS_EXE) { - if (sp->setVar->type == EJS_TYPE_OBJECT) { - - sp->setVar->objectState->preventDeleteProp = 1; - - sp->pp = ejsGetFirstProperty(sp->setVar, 0); - while (sp->pp) { - sp->nextp = ejsGetNextProperty(sp->pp, 0); - if (! sp->pp->dontEnumerate && !sp->pp->delayedDelete) { - if (each) { - sp->vp = ejsWriteVar(ep, sp->iteratorVar, - ejsGetVarPtr(sp->pp), EJS_SHALLOW_COPY); - } else { - sp->vp = ejsWriteVarAsString(ep, sp->iteratorVar, - sp->pp->name); - } - if (sp->vp == 0) { - ejsError(ep, EJS_MEMORY_ERROR, - "Can't write to variable"); - goto err; - } - - ejsLexRestoreInputState(ep, sp->bodyScript); - - state = ejsParse(ep, EJS_STATE_STMT, flags); - - if (state < 0) { - if (sp->setVar->objectState) { - sp->setVar->objectState->preventDeleteProp = 0; - } - goto done; - } - } - sp->pp = sp->nextp; - } - - /* - * Process delayed deletes - */ - if (sp->setVar->objectState) { - sp->setVar->objectState->preventDeleteProp = 0; - if (sp->setVar->objectState->delayedDeleteProp) { - sp->pp = ejsGetFirstProperty(sp->setVar, 0); - while (sp->pp) { - sp->nextp = ejsGetNextProperty(sp->pp, 0); - if (sp->pp->delayedDelete) { - ejsDeleteProperty(ep, sp->setVar, sp->pp->name); - } - sp->pp = sp->nextp; - } - sp->setVar->objectState->delayedDeleteProp = 0; - } - } - - } else { - ejsError(ep, EJS_REFERENCE_ERROR, - "Variable to iterate over is not an array or object"); - goto err; - } - } - - ejsLexRestoreInputState(ep, sp->endScript); - -done: - if (sp->endScript) { - ejsLexFreeInputState(ep, sp->endScript); - ejsLexFreeInputState(ep, sp->bodyScript); - } - - if (sp->bodyScript) { - freeInputStruct(ep, sp->bodyScript); - } - if (sp->endScript) { - freeInputStruct(ep, sp->endScript); - } - - if (sp->setVar) { - ejsFreeVar(ep, sp->setVar); - } - - popFrame(ep, sizeof(ParseForIn)); - - return state; - -err: - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Parse the for statement. Format for the expression is: - * - * for (initial; condition; incr) { - * body; - * } - */ - -static int parseRegFor(Ejs *ep, int state, int flags) -{ - EjsInput *condScript, *endScript, *bodyScript, *incrScript; - - endScript = getInputStruct(ep); - bodyScript = getInputStruct(ep); - incrScript = getInputStruct(ep); - condScript = getInputStruct(ep); - - ejsInitInputState(endScript); - ejsInitInputState(bodyScript); - ejsInitInputState(incrScript); - ejsInitInputState(condScript); - - state = parseForInner(ep, state, flags, - condScript, incrScript, bodyScript, endScript); - - ejsLexFreeInputState(ep, condScript); - ejsLexFreeInputState(ep, incrScript); - ejsLexFreeInputState(ep, endScript); - ejsLexFreeInputState(ep, bodyScript); - - freeInputStruct(ep, condScript); - freeInputStruct(ep, incrScript); - freeInputStruct(ep, endScript); - freeInputStruct(ep, bodyScript); - - return state; -} - -/******************************************************************************/ - -static int parseForInner(Ejs *ep, int state, int flags, EjsInput *condScript, - EjsInput *incrScript, EjsInput *bodyScript, EjsInput *endScript) -{ - int forFlags, cond, rs; - - mprAssert(ep); - - /* - * Evaluate the for loop initialization statement - */ - if ((state = ejsParse(ep, EJS_STATE_STMT, flags)) < 0) { - return state; - } - - /* - * The first time through, we save the current input context just prior - * to each step: prior to the conditional, the loop increment and - * the loop body. - */ - ejsLexSaveInputState(ep, condScript); - if ((rs = ejsParse(ep, EJS_STATE_COND, flags)) < 0) { - return rs; - } - - cond = (ep->result->boolean != 0); - - if (ejsLexGetToken(ep, state) != EJS_TOK_SEMI) { - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - - /* - * Don't execute the loop increment statement or the body - * first time. - */ - forFlags = flags & ~EJS_FLAGS_EXE; - ejsLexSaveInputState(ep, incrScript); - if ((rs = ejsParse(ep, EJS_STATE_EXPR, forFlags)) < 0) { - return rs; - } - - if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) { - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - - /* - * Parse the body and remember the end of the body script - */ - ejsLexSaveInputState(ep, bodyScript); - if ((rs = ejsParse(ep, EJS_STATE_STMT, forFlags)) < 0) { - return rs; - } - ejsLexSaveInputState(ep, endScript); - - /* - * Now actually do the for loop. Note loop has been rotated - */ - while (cond && (flags & EJS_FLAGS_EXE)) { - /* - * Evaluate the body - */ - ejsLexRestoreInputState(ep, bodyScript); - - if ((rs = ejsParse(ep, EJS_STATE_STMT, flags)) < 0) { - return rs; - } - - /* - * Evaluate the increment script - */ - ejsLexRestoreInputState(ep, incrScript); - if ((rs = ejsParse(ep, EJS_STATE_EXPR, flags)) < 0) { - return rs; - } - /* - * Evaluate the condition - */ - ejsLexRestoreInputState(ep, condScript); - if ((rs = ejsParse(ep, EJS_STATE_COND, flags)) < 0) { - return 0; - } - mprAssert(ep->result->type == EJS_TYPE_BOOL); - cond = (ep->result->boolean != 0); - } - - ejsLexRestoreInputState(ep, endScript); - - return state; -} - -/******************************************************************************/ -/* - * Create the bare class object - */ - -static int createClass(Ejs *ep, EjsVar *obj, const char *className, - EjsVar *baseClass) -{ - EjsVar *classObj, *existingClass; - - existingClass = ejsGetClass(ep, obj, className); - if (existingClass) { - /* - * We allow partial clases and method redefinition - * FUTURE -- should prevent this if the class is sealed. - * DISABLED Error message and return OK. - */ - /* ejsError(ep, EJS_EVAL_ERROR, "Can't create class %s", className); */ - return 0; - } - - if (baseClass == 0) { - baseClass = ejsGetClass(ep, ep->service->globalClass, "Object"); - mprAssert(baseClass); - } - - classObj = ejsCreateSimpleClass(ep, baseClass, className); - if (classObj == 0) { - ejsMemoryError(ep); - return -1; - } - mprAssert(! ejsObjIsCollectable(classObj)); - - ep->currentProperty = ejsSetPropertyAndFree(ep, obj, className, classObj); - mprAssert(ep->currentProperty); - - if (ep->currentProperty == 0) { - return -1; - } - - return 0; -} - -/******************************************************************************/ -/* - * Local vars for parseTry - */ - -typedef struct ParseTry { - EjsVar *exception; - int tid, caught, rs, catchFlags; -} ParseTry; - -/* - * Parse try block - * - * try {} - */ - -static int parseTry(Ejs *ep, int state, int flags) -{ - ParseTry *sp; - - if ((sp = pushFrame(ep, sizeof(ParseTry))) == 0) { - return EJS_STATE_ERR; - } - - mprAssert(ep); - - sp->caught = 0; - sp->exception = 0; - sp->catchFlags = flags; - - /* - * Execute the code in the try block - */ - sp->rs = ejsParse(ep, EJS_STATE_STMT, flags | EJS_FLAGS_TRY); - if (sp->rs < 0) { - if (sp->rs == EJS_STATE_ERR) { - sp->exception = ejsDupVar(ep, ep->result, EJS_SHALLOW_COPY); - if (sp->exception == 0) { - ejsMemoryError(ep); - goto err; - } - } else { - state = sp->rs; - goto done; - } - - } else { - sp->catchFlags = flags & ~EJS_FLAGS_EXE; - } - - /* - * On success path or when an exception is caught, we must parse all - * catch and finally blocks. - */ - sp->tid = getNextNonSpaceToken(ep, state); - - if (sp->tid == EJS_TOK_CATCH) { - - ep->gotException = 0; - - sp->tid = getNextNonSpaceToken(ep, state); - - if (sp->tid == EJS_TOK_LBRACE) { - /* - * Unqualified "catch " - */ - ejsLexPutbackToken(ep, sp->tid, ep->token); - if (ejsParse(ep, EJS_STATE_STMT, sp->catchFlags) >= 0) { - sp->caught++; - } - - } else if (sp->tid == EJS_TOK_LPAREN) { - - /* - * Qualified "catch (variable) " - */ - if ((sp->rs = ejsParse(ep, EJS_STATE_DEC_LIST, - sp->catchFlags | EJS_FLAGS_CATCH)) < 0) { - ejsSyntaxError(ep, "Bad catch statement"); - state = sp->rs; - goto done; - } - - sp->tid = getNextNonSpaceToken(ep, state); - if (sp->tid != EJS_TOK_RPAREN) { - ejsSyntaxError(ep, 0); - goto err; - } - - if (sp->catchFlags & EJS_FLAGS_EXE) { - if (ep->currentProperty == 0) { - ejsError(ep, EJS_EVAL_ERROR, "Can't define catch variable"); - goto err; - } - - /* - * Set the catch variable - */ - if (ejsWriteVar(ep, - ejsGetVarPtr(ep->currentProperty), sp->exception, - EJS_SHALLOW_COPY) == 0) { - ejsError(ep, EJS_EVAL_ERROR, "Can't update catch variable"); - goto err; - } - } - - /* - * Parse the catch block - */ - if ((sp->rs = ejsParse(ep, EJS_STATE_STMT, sp->catchFlags)) < 0) { - state = sp->rs; - goto done; - } - sp->caught++; - ep->gotException = 0; - } - sp->tid = getNextNonSpaceToken(ep, state); - } - - /* - * Parse the finally block - */ - if (sp->tid == EJS_TOK_FINALLY) { - if (ejsParse(ep, EJS_STATE_STMT, flags) < 0) { - goto err; - } - } else { - ejsLexPutbackToken(ep, sp->tid, ep->token); - } - - /* - * Set the exception value - */ - if (sp->exception && !sp->caught) { - ejsWriteVar(ep, ep->result, sp->exception, EJS_SHALLOW_COPY); - goto err; - } - - state = EJS_STATE_STMT_DONE; - -done: - if (sp->exception) { - ejsFreeVar(ep, sp->exception); - } - - popFrame(ep, sizeof(ParseTry)); - return state; - - -err: - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Parse throw statement - * - * throw expression - */ - -static int parseThrow(Ejs *ep, int state, int flags) -{ - int rc; - - mprAssert(ep); - - if ((rc = ejsParse(ep, EJS_STATE_EXPR, flags)) < 0) { - return rc; - } - - - if (flags & EJS_FLAGS_EXE) { - /* - * We have thrown the exception so set the state to ERR - */ - ep->gotException = 1; - return EJS_STATE_ERR; - } - return state; -} - -/******************************************************************************/ -/* - * Parse a class and module declaration - * - * class <name> [extends baseClass] { - * [public | private | ... ] var declarations ... - * [constructor] function declarations ... - * } - * - * Modules are identical except declared with a "module" instead of - * "class". Modules cannot be instantiated and are used for mixins. - * - */ - -static int parseClass(Ejs *ep, int state, int flags) -{ - int originalToken, tid, fid; - - mprAssert(ep); - - originalToken = ep->tid; - - /* - * Parse "class Name [extends BaseClass]" - */ - if (ejsParse(ep, EJS_STATE_DEC_LIST, flags | EJS_FLAGS_CLASS_DEC) < 0) { - return EJS_STATE_ERR; - } - - tid = getNextNonSpaceToken(ep, state); - - if (tid != EJS_TOK_LBRACE) { - return EJS_STATE_ERR; - } - - /* - * After parsing the class body, ep->local will contain the actual - * class/module object. So, we save ep->local by creating a new block. - */ - if (flags & EJS_FLAGS_EXE) { - fid = ejsSetBlock(ep, ejsGetVarPtr(ep->currentProperty)); - ejsSetVarName(ep, ep->local, ep->currentProperty->name); - - } else { - fid = -1; - } - - /* FUTURE -- should prevent modules from being instantiated */ - - /* - * Parse class body - */ - do { - state = ejsParse(ep, EJS_STATE_STMT, flags); - if (state < 0) { - if (fid >= 0) { - ejsCloseBlock(ep, fid); - } - return state; - } - tid = getNextNonSpaceToken(ep, state); - if (tid == EJS_TOK_RBRACE) { - break; - } - ejsLexPutbackToken(ep, tid, ep->token); - - } while (state >= 0); - - if (fid >= 0) { - ejsCloseBlock(ep, fid); - } - - if (tid != EJS_TOK_RBRACE) { - ejsSyntaxError(ep, 0); - state = EJS_STATE_ERR; - } - - return state; -} - -/******************************************************************************/ -/* - * Parse a function declaration - */ - -static int parseFunction(Ejs *ep, int state, int flags) -{ - EjsInput *endScript, *bodyScript; - EjsProperty *pp; - EjsVar *func, *funcProp, *currentObj, *vp, *baseClass; - char *procName; - int varFlags, len, tid, bodyFlags, innerState; - - mprAssert(ep); - - func = 0; - varFlags = 0; - - /* - * method <name>(arg, arg, arg) { body }; - * method name(arg, arg, arg) { body }; - */ - - tid = ejsLexGetToken(ep, state); - - if (tid == EJS_TOK_GET) { - varFlags |= EJS_GET_ACCESSOR; - tid = ejsLexGetToken(ep, state); - - } else if (tid == EJS_TOK_SET) { - varFlags |= EJS_SET_ACCESSOR; - tid = ejsLexGetToken(ep, state); - } - - if (tid == EJS_TOK_ID) { - if (varFlags & EJS_SET_ACCESSOR) { - - if (mprAllocStrcat(MPR_LOC_ARGS(ep), &procName, EJS_MAX_ID + 5, - 0, "-set-", ep->token, 0) < 0) { - ejsError(ep, EJS_SYNTAX_ERROR, - "Name %s is too long", ep->token); - return EJS_STATE_ERR; - } - - } else { - procName = mprStrdup(ep, ep->token); - } - - tid = ejsLexGetToken(ep, state); - - } else { - procName = 0; - } - - if (tid != EJS_TOK_LPAREN) { - mprFree(procName); - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - - /* - * Hand craft the method value structure. - */ - if (flags & EJS_FLAGS_EXE) { - func = ejsCreateMethodVar(ep, 0, 0, 0); - if (func == 0) { - mprFree(procName); - ejsMemoryError(ep); - return EJS_STATE_ERR; - } - func->flags = varFlags; - } - - tid = ejsLexGetToken(ep, state); - while (tid == EJS_TOK_ID) { - if (flags & EJS_FLAGS_EXE) { - mprAddItem(func->method.args, - mprStrdup(func->method.args, ep->token)); - } - tid = ejsLexGetToken(ep, state); - if (tid == EJS_TOK_RPAREN || tid != EJS_TOK_COMMA) { - break; - } - tid = ejsLexGetToken(ep, state); - } - if (tid != EJS_TOK_RPAREN) { - mprFree(procName); - ejsFreeVar(ep, func); - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - - /* Allow new lines before opening brace */ - do { - tid = ejsLexGetToken(ep, state); - } while (tid == EJS_TOK_NEWLINE); - - if (tid != EJS_TOK_LBRACE) { - mprFree(procName); - ejsFreeVar(ep, func); - ejsSyntaxError(ep, 0); - return EJS_STATE_ERR; - } - - /* - * Register the method name early to allow for recursive - * method calls (see note in ECMA standard, page 71) - */ - funcProp = 0; - if (flags & EJS_FLAGS_EXE && procName) { - currentObj = pickSpace(ep, 0, procName, flags | EJS_FLAGS_LOCAL); - pp = ejsSetProperty(ep, currentObj, procName, func); - if (pp == 0) { - ejsFreeVar(ep, func); - ejsMemoryError(ep); - return EJS_STATE_ERR; - } - funcProp = ejsGetVarPtr(pp); - } - - - bodyScript = getInputStruct(ep); - - /* - * Parse the method body. Turn execute off. - */ - bodyFlags = flags & ~EJS_FLAGS_EXE; - ejsLexSaveInputState(ep, bodyScript); - - do { - innerState = ejsParse(ep, EJS_STATE_STMT, bodyFlags); - } while (innerState == EJS_STATE_STMT_DONE); - - tid = ejsLexGetToken(ep, state); - - if (innerState != EJS_STATE_STMT_BLOCK_DONE || tid != EJS_TOK_RBRACE) { - mprFree(procName); - ejsFreeVar(ep, func); - ejsLexFreeInputState(ep, bodyScript); - if (innerState != EJS_STATE_ERR) { - ejsSyntaxError(ep, 0); - } - freeInputStruct(ep, bodyScript); - return EJS_STATE_ERR; - } - - if (flags & EJS_FLAGS_EXE) { - endScript = getInputStruct(ep); - ejsLexSaveInputState(ep, endScript); - - /* - * Save the method body between the starting and ending parse - * positions. Overwrite the trailing '}' with a null. - */ - len = endScript->scriptServp - bodyScript->scriptServp; - func->method.body = mprAlloc(ep, len + 1); - memcpy(func->method.body, bodyScript->scriptServp, len); - - if (len <= 0) { - func->method.body[0] = '\0'; - } else { - func->method.body[len - 1] = '\0'; - } - ejsLexFreeInputState(ep, bodyScript); - ejsLexFreeInputState(ep, endScript); - freeInputStruct(ep, endScript); - - /* - * If we are in an assignment, don't register the method name, rather - * return the method structure in the parser result. - */ - if (procName) { - currentObj = pickSpace(ep, 0, procName, flags | EJS_FLAGS_LOCAL); - pp = ejsSetProperty(ep, currentObj, procName, func); - if (pp == 0) { - ejsFreeVar(ep, func); - ejsMemoryError(ep); - return EJS_STATE_ERR; - } - - if (currentObj->objectState->className && - strcmp(currentObj->objectState->className, procName) == 0) { - baseClass = currentObj->objectState->baseClass; - if (baseClass) { - if (strstr(func->method.body, "super(") != 0) { - funcProp->callsSuper = 1; - /* - * Define super() to point to the baseClass constructor - */ - vp = ejsGetPropertyAsVar(ep, baseClass, - baseClass->objectState->className); - if (vp) { - mprAssert(vp); - if (ejsSetProperty(ep, currentObj, "super", - vp) == 0) { - ejsFreeVar(ep, func); - ejsMemoryError(ep); - return EJS_STATE_ERR; - } - } - } - } - } - } - /* - * Always return the function. Try for all stmts to be expressions. - */ - /* MOB - rc */ - ejsWriteVar(ep, ep->result, func, EJS_SHALLOW_COPY); - } - freeInputStruct(ep, bodyScript); - - mprFree(procName); - ejsFreeVar(ep, func); - - return state; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct ParseMethod { - EjsProc proc, *saveProc; - EjsVar *saveObj, *newObj; - int saveObjPerm, rc; - -} ParseMethod; - -/* - * Parse a method name and invoke the method. See parseFunction for - * function declarations. - */ - -static int parseMethod(Ejs *ep, int state, int flags, char *id) -{ - ParseMethod *sp; - - if ((sp = pushFrame(ep, sizeof(ParseMethod))) == 0) { - return EJS_STATE_ERR; - } - - /* - * Must save any current ep->proc value for the current stack frame - * to allow for recursive method calls. - */ - sp->saveProc = (ep->proc) ? ep->proc: 0; - - memset(&sp->proc, 0, sizeof(EjsProc)); - sp->proc.procName = mprStrdup(ep, id); - sp->proc.fn = &ep->currentProperty->var; - sp->proc.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); - ep->proc = &sp->proc; - -#if BLD_DEBUG - if (strcmp(sp->proc.procName, "printv") == 0) { - flags |= EJS_FLAGS_TRACE_ARGS; - } -#endif - - if (flags & EJS_FLAGS_EXE) { - ejsClearVar(ep, ep->result); - } - - if (! (flags & EJS_FLAGS_NO_ARGS)) { - sp->saveObj = ep->currentObj; - sp->saveObjPerm = ejsMakeObjPermanent(sp->saveObj, 1); - sp->rc = ejsParse(ep, EJS_STATE_ARG_LIST, flags); - ejsMakeObjPermanent(sp->saveObj, sp->saveObjPerm); - if (sp->rc < 0) { - goto err; - } - ep->currentObj = sp->saveObj; - } - -#if BLD_DEBUG - flags &= ~EJS_FLAGS_TRACE_ARGS; -#endif - - /* - * Evaluate the method if required - */ - if (flags & EJS_FLAGS_EXE) { - if (flags & EJS_FLAGS_NEW) { - sp->newObj = ejsCreateObjUsingArgv(ep, ep->currentObj, - sp->proc.procName, sp->proc.args); - - if (sp->newObj == 0) { - state = EJS_STATE_ERR; - - } else { - mprAssert(! ejsObjIsCollectable(sp->newObj)); - - /* - * Return the newly created object as the result of the - * command. NOTE: newObj may not be an object! - */ - /* MOB - rc */ - ejsWriteVar(ep, ep->result, sp->newObj, EJS_SHALLOW_COPY); - if (ejsVarIsObject(sp->newObj)) { - ejsMakeObjLive(sp->newObj, 1); - mprAssert(ejsObjIsCollectable(sp->newObj)); - mprAssert(ejsBlockInUse(sp->newObj)); - } - ejsFreeVar(ep, sp->newObj); - } - - } else { - - if (evalMethod(ep, ep->currentObj, &sp->proc, flags) < 0) { - /* Methods must call ejsError to set exceptions */ - state = EJS_STATE_ERR; - } - } - } - - if (! (flags & EJS_FLAGS_NO_ARGS)) { - if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) { - if (state != EJS_STATE_ERR) { - ejsSyntaxError(ep, 0); - } - state = EJS_STATE_ERR; - } - } - -done: - freeProc(ep, &sp->proc); - ep->proc = sp->saveProc; - - popFrame(ep, sizeof(ParseMethod)); - return state; - -err: - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Parse an identifier. This is a segment of a fully qualified variable. - * May come here for an initial identifier or for property names - * after a "." or "[...]". - */ - -static int parseId(Ejs *ep, int state, int flags, char **id, int *done) -{ - EjsVar *null; - int tid; - - mprFree(*id); - *id = mprStrdup(ep, ep->token); - - if (ep->currentObj == 0) { - /* First identifier segement */ - ep->currentObj = pickSpace(ep, state, *id, flags); - } - - tid = ejsLexGetToken(ep, state); - if (tid == EJS_TOK_ASSIGNMENT) { - flags |= EJS_FLAGS_LHS; - } - - /* - * Find the referenced variable and store it in currentProperty. - */ - if (flags & EJS_FLAGS_EXE) { - ep->currentProperty = searchSpacesForProperty(ep, state, - ep->currentObj, *id, flags); - - /* - * Handle properties that have been deleted inside an enumeration - */ - if (ep->currentProperty && ep->currentProperty->delayedDelete) { - ep->currentProperty = 0; - } - - if (ep->currentProperty && - ejsVarIsMethod(&ep->currentProperty->var) && - tid != EJS_TOK_LPAREN) { - if (ep->currentProperty->var.flags & EJS_GET_ACCESSOR) { - ejsLexPutbackToken(ep, tid, ep->token); - state = parseMethod(ep, state, flags | EJS_FLAGS_NO_ARGS, *id); - if (ep->flags & EJS_FLAGS_EXIT) { - state = EJS_STATE_RET; - } - if (state >= 0) { - ejsSetVarName(ep, ep->result, ep->currentProperty->name); - } - return state; - } - } - /* - * OPT. We should not have to do this always - */ - updateResult(ep, state, flags, ejsGetVarPtr(ep->currentProperty)); - } - - flags &= ~EJS_FLAGS_LHS; - - if (tid == EJS_TOK_LPAREN) { - if (ep->currentProperty == 0 && (flags & EJS_FLAGS_EXE)) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Method name not defined \"%s\"", *id); - return EJS_STATE_ERR; - } - ejsLexPutbackToken(ep, EJS_TOK_METHOD_NAME, ep->token); - return state; - } - - if (tid == EJS_TOK_PERIOD || tid == EJS_TOK_LBRACKET || - tid == EJS_TOK_ASSIGNMENT || tid == EJS_TOK_INC_DEC) { - ejsLexPutbackToken(ep, tid, ep->token); - return state; - } - - if (flags & EJS_FLAGS_CLASS_DEC) { - if (tid == EJS_TOK_LBRACE || tid == EJS_TOK_EXTENDS) { - ejsLexPutbackToken(ep, tid, ep->token); - return state; - } - } - - if (flags & EJS_FLAGS_DELETE) { - if (tid == EJS_TOK_RBRACE) { - ejsLexPutbackToken(ep, tid, ep->token); - } - } - - /* - * Only come here for variable access and declarations. - * Assignment handled elsewhere. - */ - if (flags & EJS_FLAGS_EXE) { - if (state == EJS_STATE_DEC) { - /* - * Declare a variable. Standard allows: var x ; var x ; - */ -#if DISABLED - if (ep->currentProperty != 0) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Variable already defined \"%s\"", *id); - return EJS_STATE_ERR; - } -#endif - /* - * Create or overwrite if it already exists - * Set newly declared variables to the null value. - */ - null = ejsCreateNullVar(ep); - ep->currentProperty = ejsSetPropertyAndFree(ep, ep->currentObj, - *id, null); - ejsClearVar(ep, ep->result); - - } else if (flags & EJS_FLAGS_FORIN) { - /* - * This allows "for (x" when x has not yet been defined - */ - if (ep->currentProperty == 0) { - /* MOB -- return code */ - ep->currentProperty = ejsCreateProperty(ep, - ep->currentObj, *id); - } - - } else if (ep->currentProperty == 0) { - - if (ep->currentObj && ((ep->currentObj == ep->global || - (ep->currentObj == ep->local)))) { - /* - * Test against currentObj and not currentObj->objectState - * as we must allow "i = global.x" and not allow - * "i = x" where x does not exist. - */ - ejsError(ep, EJS_REFERENCE_ERROR, - "Undefined variable \"%s\"", *id); - return EJS_STATE_ERR; - } - - if (flags & EJS_FLAGS_DELETE) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Undefined variable \"%s\"", *id); - return EJS_STATE_ERR; - } - } - } - ejsLexPutbackToken(ep, tid, ep->token); - if (tid == EJS_TOK_RBRACKET || tid == EJS_TOK_COMMA || - tid == EJS_TOK_IN) { - *done = 1; - } - return state; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct ParseIf { - int ifResult, thenFlags, elseFlags, tid, rs; -} ParseIf; - -/* - * Parse an "if" statement - */ - -static int parseIf(Ejs *ep, int state, int flags, int *done) -{ - ParseIf *sp; - - if ((sp = pushFrame(ep, sizeof(ParseIf))) == 0) { - return EJS_STATE_ERR; - } - - if (state != EJS_STATE_STMT) { - goto err; - } - if (ejsLexGetToken(ep, state) != EJS_TOK_LPAREN) { - goto err; - } - - /* - * Evaluate the entire condition list "(condition)" - */ - if (ejsParse(ep, EJS_STATE_COND, flags) < 0) { - goto err; - } - if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) { - goto err; - } - - /* - * This is the "then" case. We need to always parse both cases and - * execute only the relevant case. - */ - sp->ifResult = ejsVarToBoolean(ep->result); - if (sp->ifResult) { - sp->thenFlags = flags; - sp->elseFlags = flags & ~EJS_FLAGS_EXE; - } else { - sp->thenFlags = flags & ~EJS_FLAGS_EXE; - sp->elseFlags = flags; - } - - /* - * Process the "then" case. - */ - if ((sp->rs = ejsParse(ep, EJS_STATE_STMT, sp->thenFlags)) < 0) { - if (! ep->gotException) { - state = sp->rs; - goto done; - } - } - - /* - * Check to see if there is an "else" case - */ - removeNewlines(ep, state); - sp->tid = ejsLexGetToken(ep, state); - if (sp->tid != EJS_TOK_ELSE) { - ejsLexPutbackToken(ep, sp->tid, ep->token); - *done = 1; - if (ep->gotException) { - goto err; - } - goto done; - } - - /* - * Process the "else" case. - */ - state = ejsParse(ep, EJS_STATE_STMT, sp->elseFlags); - -done: - *done = 1; - if (ep->gotException) { - state = EJS_STATE_ERR; - } - popFrame(ep, sizeof(ParseIf)); - return state; - - -err: - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Parse a postix "++" or "--" statement - */ - -static int parseInc(Ejs *ep, int state, int flags) -{ - EjsVar *one; - - if (! (flags & EJS_FLAGS_EXE)) { - return state; - } - - if (ep->currentProperty == 0) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Undefined variable \"%s\"", ep->token); - return EJS_STATE_ERR; - } - one = ejsCreateIntegerVar(ep, 1); - if (evalExpr(ep, &ep->currentProperty->var, (int) *ep->token, one) < 0) { - ejsFreeVar(ep, one); - return EJS_STATE_ERR; - } - if (ejsWriteVar(ep, &ep->currentProperty->var, ep->result, - EJS_SHALLOW_COPY) < 0) { - ejsError(ep, EJS_IO_ERROR, "Can't write to variable"); - ejsFreeVar(ep, one); - return EJS_STATE_ERR; - } - ejsFreeVar(ep, one); - return state; -} - -/******************************************************************************/ -/* - * Evaluate a condition. Implements &&, ||, !. Returns with a boolean result - * in ep->result. Returns EJS_STATE_ERR on errors, zero if successful. - */ - -static int evalCond(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs) -{ - int l, r, lval; - - mprAssert(rel > 0); - - l = ejsVarToBoolean(lhs); - r = ejsVarToBoolean(rhs); - - switch (rel) { - case EJS_COND_AND: - lval = l && r; - break; - case EJS_COND_OR: - lval = l || r; - break; - default: - ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel); - return -1; - } - - /* MOB - rc */ - ejsWriteVarAsBoolean(ep, ep->result, lval); - return 0; -} - - -/******************************************************************************/ -/* - * return true if this string is a valid number - */ - -static int stringIsNumber(const char *s) -{ - char *endptr = NULL; - - if (s == NULL || *s == 0) { - return 0; - } - /* MOB -- not ideal */ -#if BREW - /* MOB this should check all digits and not just the first. */ - /* Does not support floating point - easy */ - - if (isdigit(*s) || (*s == '-' && isdigit(s[1]))) { - return 1; - } -#else - strtod(s, &endptr); -#endif - if (endptr != NULL && *endptr == 0) { - return 1; - } - return 0; -} - -/******************************************************************************/ -/* - * Evaluate an operation. Returns with the result in ep->result. Returns -1 - * on errors, otherwise zero is returned. - */ - -static int evalExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs) -{ - EjsNum lval; - char *str; - int rc; - - mprAssert(rel > 0); - str = 0; - lval = 0; - - /* - * Type conversion. This is tricky and must be according to the standard. - * Only numbers (including floats) and strings can be compared. All other - * types are first converted to numbers by preference and if that fails, - * to strings. - * - * MOB -- should we do "valueOf" here also. - */ - if (lhs->type == EJS_TYPE_OBJECT && - (rhs->type != EJS_TYPE_OBJECT && - (rhs->type != EJS_TYPE_UNDEFINED && rhs->type != EJS_TYPE_NULL))) { - if (ejsVarIsNumber(rhs)) { - if (ejsRunMethod(ep, lhs, "toValue", 0) == 0) { - /* MOB - rc */ - ejsWriteVar(ep, lhs, ep->result, EJS_SHALLOW_COPY); - } else { - if (ejsRunMethod(ep, lhs, "toString", 0) == 0) { - /* MOB - rc */ - ejsWriteVar(ep, lhs, ep->result, EJS_SHALLOW_COPY); - } - } - - } else { - if (ejsRunMethod(ep, lhs, "toString", 0) == 0) { - /* MOB - rc */ - ejsWriteVar(ep, lhs, ep->result, EJS_SHALLOW_COPY); - } else { - if (ejsRunMethod(ep, lhs, "toValue", 0) == 0) { - /* MOB - rc */ - ejsWriteVar(ep, lhs, ep->result, EJS_SHALLOW_COPY); - } - } - } - /* Nothing more can be done */ - } - - if (rhs->type == EJS_TYPE_OBJECT && - (lhs->type != EJS_TYPE_OBJECT && - (lhs->type != EJS_TYPE_UNDEFINED && lhs->type != EJS_TYPE_NULL))) { - if (ejsVarIsNumber(lhs)) { - /* If LHS is number, then convert to a value first */ - if (ejsRunMethod(ep, rhs, "toValue", 0) == 0) { - /* MOB - rc */ - ejsWriteVar(ep, rhs, ep->result, EJS_SHALLOW_COPY); - } else { - if (ejsRunMethod(ep, rhs, "toString", 0) == 0) { - /* MOB - rc */ - ejsWriteVar(ep, rhs, ep->result, EJS_SHALLOW_COPY); - } - } - - } else { - /* If LHS is not a number, then convert to a string first */ - if (ejsRunMethod(ep, rhs, "toString", 0) == 0) { - /* MOB - rc */ - ejsWriteVar(ep, rhs, ep->result, EJS_SHALLOW_COPY); - - } else { - if (ejsRunMethod(ep, rhs, "toValue", 0) == 0) { - /* MOB - rc */ - ejsWriteVar(ep, rhs, ep->result, EJS_SHALLOW_COPY); - } - } - } - /* Nothing more can be done */ - } - - /* - * undefined and null are special, in that they don't get promoted when - * comparing. - */ - if (rel == EJS_EXPR_EQ || rel == EJS_EXPR_NOTEQ) { - if (lhs->type == EJS_TYPE_UNDEFINED || - rhs->type == EJS_TYPE_UNDEFINED) { - return evalBoolExpr(ep, - lhs->type == EJS_TYPE_UNDEFINED, - rel, - rhs->type == EJS_TYPE_UNDEFINED); - } - - if (lhs->type == EJS_TYPE_NULL || rhs->type == EJS_TYPE_NULL) { - return evalBoolExpr(ep, - lhs->type == EJS_TYPE_NULL, - rel, - rhs->type == EJS_TYPE_NULL); - } - } - - /* - * From here on, lhs and rhs may contain allocated data (strings), so - * we must always destroy before overwriting. - */ - - /* - * Only allow a few bool operations. Otherwise convert to number. - */ - if (lhs->type == EJS_TYPE_BOOL && rhs->type == EJS_TYPE_BOOL && - (rel != EJS_EXPR_EQ && rel != EJS_EXPR_NOTEQ && - rel != EJS_EXPR_BOOL_COMP)) { - ejsWriteVarAsNumber(ep, lhs, ejsVarToNumber(lhs)); - } - - /* - * Types do not match, so try to coerce the right operand to match the left - * But first, try to convert a left operand that is a numeric stored as a - * string, into a numeric. - */ - if (lhs->type != rhs->type) { - if (lhs->type == EJS_TYPE_STRING) { - if (stringIsNumber(lhs->string)) { - ejsWriteVarAsNumber(ep, lhs, ejsVarToNumber(lhs)); - - /* Examine further below */ - - } else { - /* - * Convert the RHS to a string - * MOB rc - */ - str = ejsVarToString(ep, rhs); - ejsWriteVarAsString(ep, rhs, str); - } - -#if BLD_FEATURE_FLOATING_POINT - } else if (lhs->type == EJS_TYPE_FLOAT) { - /* - * Convert rhs to floating - */ - ejsWriteVarAsFloat(ep, rhs, ejsVarToFloat(rhs)); - -#endif -#if BLD_FEATURE_INT64 - } else if (lhs->type == EJS_TYPE_INT64) { - /* - * Convert the rhs to 64 bit - */ - ejsWriteVarAsInteger64(ep, rhs, ejsVarToInteger64(rhs)); -#endif - } else if (lhs->type == EJS_TYPE_BOOL || lhs->type == EJS_TYPE_INT) { - - if (rhs->type == EJS_TYPE_STRING) { - if (stringIsNumber(rhs->string)) { - ejsWriteVarAsNumber(ep, rhs, ejsVarToNumber(rhs)); - } else { - /* - * Convert to lhs to a string - */ - str = ejsVarToString(ep, lhs); - /* MOB -- rc */ - if (str) { - ejsWriteVarAsString(ep, lhs, str); - } - } - -#if BLD_FEATURE_FLOATING_POINT - } else if (rhs->type == EJS_TYPE_FLOAT) { - /* - * Convert lhs to floating - */ - ejsWriteVarAsFloat(ep, lhs, ejsVarToFloat(lhs)); -#endif - - } else { - /* - * Forcibly convert both operands to numbers - */ - ejsWriteVarAsNumber(ep, lhs, ejsVarToNumber(lhs)); - ejsWriteVarAsNumber(ep, rhs, ejsVarToNumber(rhs)); - } - } - } - - /* - * We have failed to coerce the types to be the same. Special case here - * for undefined and null. We need to allow comparisions against these - * special values. - */ - if (lhs->type == EJS_TYPE_UNDEFINED || lhs->type == EJS_TYPE_NULL) { - switch (rel) { - case EJS_EXPR_EQ: - lval = lhs->type == rhs->type; - break; - case EJS_EXPR_NOTEQ: - lval = lhs->type != rhs->type; - break; - case EJS_EXPR_BOOL_COMP: - lval = ! ejsVarToBoolean(rhs); - break; - default: - ejsWriteVar(ep, ep->result, rhs, EJS_SHALLOW_COPY); - return 0; - } - ejsWriteVarAsBoolean(ep, ep->result, lval); - return 0; - } - - /* - * Types are the same here - */ - switch (lhs->type) { - default: - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - /* Should be handled above */ - mprAssert(0); - return 0; - - case EJS_TYPE_STRING_CMETHOD: - case EJS_TYPE_CMETHOD: - case EJS_TYPE_METHOD: - case EJS_TYPE_PTR: - ejsWriteVarAsBoolean(ep, ep->result, 0); - return 0; - - case EJS_TYPE_OBJECT: - rc = evalObjExpr(ep, lhs, rel, rhs); - break; - - case EJS_TYPE_BOOL: - rc = evalBoolExpr(ep, lhs->boolean, rel, rhs->boolean); - break; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - rc = evalFloatExpr(ep, lhs->floating, rel, rhs->floating); - break; -#endif - - case EJS_TYPE_INT: - rc = evalNumericExpr(ep, (EjsNum) lhs->integer, rel, - (EjsNum) rhs->integer); - break; - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - rc = evalNumericExpr(ep, (EjsNum) lhs->integer64, rel, - (EjsNum) rhs->integer64); - break; -#endif - - case EJS_TYPE_STRING: - rc = evalStringExpr(ep, lhs, rel, rhs); - } - - /* MOB */ - if (lhs->type == EJS_TYPE_OBJECT) { - ejsMakeObjLive(lhs, 0); - mprAssert(lhs->objectState->alive == 0); - } - if (rhs->type == EJS_TYPE_OBJECT) { - ejsMakeObjLive(rhs, 0); - mprAssert(rhs->objectState->alive == 0); - } - - return rc; -} - -/******************************************************************************/ -#if BLD_FEATURE_FLOATING_POINT -/* - * Expressions with floating operands - */ - -static int evalFloatExpr(Ejs *ep, double l, int rel, double r) -{ - double lval; - int logical; - - lval = 0; - logical = 0; - - switch (rel) { - case EJS_EXPR_PLUS: - lval = l + r; - break; - case EJS_EXPR_INC: - lval = l + 1; - break; - case EJS_EXPR_MINUS: - lval = l - r; - break; - case EJS_EXPR_DEC: - lval = l - 1; - break; - case EJS_EXPR_MUL: - lval = l * r; - break; - case EJS_EXPR_DIV: - lval = l / r; - break; - default: - logical++; - break; - } - - /* - * Logical operators - */ - if (logical) { - - switch (rel) { - case EJS_EXPR_EQ: - lval = l == r; - break; - case EJS_EXPR_NOTEQ: - lval = l != r; - break; - case EJS_EXPR_LESS: - lval = (l < r) ? 1 : 0; - break; - case EJS_EXPR_LESSEQ: - lval = (l <= r) ? 1 : 0; - break; - case EJS_EXPR_GREATER: - lval = (l > r) ? 1 : 0; - break; - case EJS_EXPR_GREATEREQ: - lval = (l >= r) ? 1 : 0; - break; - case EJS_EXPR_BOOL_COMP: - lval = (r == 0) ? 1 : 0; - break; - default: - ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel); - return -1; - } - ejsWriteVarAsBoolean(ep, ep->result, lval != 0); - - } else { - ejsWriteVarAsFloat(ep, ep->result, lval); - } - return 0; -} - -#endif /* BLD_FEATURE_FLOATING_POINT */ -/******************************************************************************/ -/* - * Expressions with object operands - */ - -static int evalObjExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs) -{ - int lval; - - switch (rel) { - case EJS_EXPR_EQ: - lval = lhs->objectState == rhs->objectState; - break; - case EJS_EXPR_NOTEQ: - lval = lhs->objectState != rhs->objectState; - break; - default: - ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel); - return -1; - } - ejsWriteVarAsBoolean(ep, ep->result, lval); - return 0; -} - -/******************************************************************************/ -/* - * Expressions with boolean operands - */ - -static int evalBoolExpr(Ejs *ep, int l, int rel, int r) -{ - int lval; - - switch (rel) { - case EJS_EXPR_EQ: - lval = l == r; - break; - case EJS_EXPR_NOTEQ: - lval = l != r; - break; - case EJS_EXPR_BOOL_COMP: - lval = (r == 0) ? 1 : 0; - break; - default: - ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel); - return -1; - } - ejsWriteVarAsBoolean(ep, ep->result, lval); - return 0; -} - -/******************************************************************************/ -/* - * Expressions with numeric operands - */ - -static int evalNumericExpr(Ejs *ep, EjsNum l, int rel, EjsNum r) -{ - EjsNum lval; - int logical; - - lval = 0; - logical = 0; - - switch (rel) { - case EJS_EXPR_PLUS: - lval = l + r; - break; - case EJS_EXPR_INC: - lval = l + 1; - break; - case EJS_EXPR_MINUS: - lval = l - r; - break; - case EJS_EXPR_DEC: - lval = l - 1; - break; - case EJS_EXPR_MUL: - lval = l * r; - break; - case EJS_EXPR_DIV: - if (r != 0) { - lval = l / r; - } else { - ejsError(ep, EJS_RANGE_ERROR, "Divide by zero"); - return -1; - } - break; - case EJS_EXPR_MOD: - if (r != 0) { - lval = l % r; - } else { - ejsError(ep, EJS_RANGE_ERROR, "Modulo zero"); - return -1; - } - break; - case EJS_EXPR_LSHIFT: - lval = l << r; - break; - case EJS_EXPR_RSHIFT: - lval = l >> r; - break; - - default: - logical++; - break; - } - - /* - * Logical operators - */ - if (logical) { - - switch (rel) { - case EJS_EXPR_EQ: - lval = l == r; - break; - case EJS_EXPR_NOTEQ: - lval = l != r; - break; - case EJS_EXPR_LESS: - lval = (l < r) ? 1 : 0; - break; - case EJS_EXPR_LESSEQ: - lval = (l <= r) ? 1 : 0; - break; - case EJS_EXPR_GREATER: - lval = (l > r) ? 1 : 0; - break; - case EJS_EXPR_GREATEREQ: - lval = (l >= r) ? 1 : 0; - break; - case EJS_EXPR_BOOL_COMP: - lval = (r == 0) ? 1 : 0; - break; - default: - ejsError(ep, EJS_SYNTAX_ERROR, "Bad operator %d", rel); - return -1; - } - ejsWriteVarAsBoolean(ep, ep->result, lval != 0); - - } else { - ejsWriteVarAsNumber(ep, ep->result, lval); - } - return 0; -} - -/******************************************************************************/ -/* - * Expressions with string operands - */ - -static int evalStringExpr(Ejs *ep, EjsVar *lhs, int rel, EjsVar *rhs) -{ - int lval; - - mprAssert(ep); - mprAssert(lhs); - mprAssert(rhs); - - switch (rel) { - case EJS_EXPR_LESS: - lval = strcmp(lhs->string, rhs->string) < 0; - break; - case EJS_EXPR_LESSEQ: - lval = strcmp(lhs->string, rhs->string) <= 0; - break; - case EJS_EXPR_GREATER: - lval = strcmp(lhs->string, rhs->string) > 0; - break; - case EJS_EXPR_GREATEREQ: - lval = strcmp(lhs->string, rhs->string) >= 0; - break; - case EJS_EXPR_EQ: - lval = strcmp(lhs->string, rhs->string) == 0; - break; - case EJS_EXPR_NOTEQ: - lval = strcmp(lhs->string, rhs->string) != 0; - break; - case EJS_EXPR_PLUS: - /* - * This differs from all the above operations. We append rhs to lhs. - */ - ejsClearVar(ep, ep->result); - ejsStrcat(ep, ep->result, lhs); - ejsStrcat(ep, ep->result, rhs); - return 0; - - case EJS_EXPR_INC: - case EJS_EXPR_DEC: - case EJS_EXPR_MINUS: - case EJS_EXPR_DIV: - case EJS_EXPR_MOD: - case EJS_EXPR_LSHIFT: - case EJS_EXPR_RSHIFT: - default: - ejsSyntaxError(ep, "Bad operator"); - return -1; - } - - ejsWriteVarAsBoolean(ep, ep->result, lval); - return 0; -} - -/******************************************************************************/ -/* - * Evaluate a method. obj is set to the current object if a method is being - * run. - */ - -static int evalMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, int flags) -{ - EjsProperty *pp; - EjsVar *saveThis, *prototype; - int saveThisPerm, rc, fid; - - mprAssert(ep); - - rc = 0; - fid = -1; - saveThis = 0; - saveThisPerm = 0; - prototype = proc->fn; - - if (prototype == 0) { - ejsError(ep, EJS_EVAL_ERROR, "Undefined method"); - return EJS_STATE_ERR; - } - - if (prototype->type == EJS_TYPE_OBJECT) { - prototype = ejsGetPropertyAsVar(ep, prototype, proc->procName); - } - - if (prototype) { - /* - * Create a new variable stack frame. ie. new local variables. - * Some C methods (eg. include) don't create a new local context. - */ - if (! (prototype->flags & EJS_NO_LOCAL)) { - fid = ejsOpenBlock(ep); - if (fid < 0) { - return EJS_STATE_ERR; - } - mprAssert(ejsBlockInUse(ep->local)); - - pp = ejsSetProperty(ep, ep->local, "this", obj); - ejsMakePropertyEnumerable(pp, 0); - - /* - * Optimization. Save "this" during this block. - */ - saveThis = ep->thisObject; - ep->thisObject = ejsGetVarPtr(pp); - saveThisPerm = ejsMakeObjPermanent(saveThis, 1); - } - - switch (prototype->type) { - default: - mprAssert(0); - break; - - case EJS_TYPE_STRING_CMETHOD: - rc = callStringCMethod(ep, obj, proc, prototype); - break; - - case EJS_TYPE_CMETHOD: - rc = callCMethod(ep, obj, proc, prototype); - break; - - case EJS_TYPE_METHOD: - rc = callMethod(ep, obj, proc, prototype); - break; - } - - if (fid >= 0) { - ejsMakeObjPermanent(saveThis, saveThisPerm); - ep->thisObject = saveThis; - mprAssert(ejsBlockInUse(ep->local)); - mprAssert(ejsBlockInUse(ep->thisObject)); - ejsCloseBlock(ep, fid); - } - } - - return rc; -} - -/******************************************************************************/ -/* - * Create a new object and call all required constructors. - * obj may be null in which case we look globally for className. - */ - -EjsVar *ejsCreateObjUsingArgvInternal(EJS_LOC_DEC(ep, loc), EjsVar *obj, - const char *className, MprArray *args) -{ - EjsVar *baseClass, *objectClass, *thisObj; - int rc; - - mprAssert(className && *className); - - /* - * Create a new object of the required class and pass it into the - * constructor as the "this" local variable. - */ - baseClass = ejsGetClass(ep, obj, className); - if (baseClass == 0) { - - if (obj && obj->objectState->className && - strcmp(obj->objectState->className, className) == 0) { - /* - * Handle case where we are calling the constructor inside - * the class. In this case, obj == baseClass. - */ - thisObj = ejsCreateSimpleObjUsingClassInt(EJS_LOC_PASS(ep, loc), - obj); - - } else { - - /* - * If the baseClass does not exist, try to create an Object - * We do this for compatibility with JS 1.5 style new Function. - * MOB -- but this masks an error if we really need className. - */ - objectClass = ejsGetClass(ep, 0, "Object"); - thisObj = ejsCreateSimpleObjUsingClassInt(EJS_LOC_PASS(ep, loc), - objectClass); - } - - } else { - thisObj = ejsCreateSimpleObjUsingClassInt(EJS_LOC_PASS(ep, loc), - baseClass); - } - - if (thisObj == 0) { - ejsMemoryError(ep); - return 0; - } - - /* - * Make the object permanent. While currently not alive, the constructor - * below may make the object alive. - */ - ejsMakeObjPermanent(thisObj, 1); - mprAssert(! ejsObjIsCollectable(thisObj)); - - rc = 0; - if (baseClass) { - if (! baseClass->objectState->noConstructor) { - rc = callConstructor(ep, thisObj, baseClass, args); - } - } else { - /* - * className is the function name when calling new on functions - */ - rc = ejsRunMethod(ep, thisObj, className, args); - } - - /* - * Constructor may change the type to a non-object. - * Function() does this. Ensure object is not collectable yet. - */ - if (ejsVarIsObject(thisObj)) { - ejsMakeObjPermanent(thisObj, 0); - ejsMakeObjLive(thisObj, 0); - } - - if (rc < 0) { - if (rc == MPR_ERR_NOT_FOUND) { - /* No constructor (default) */ - return thisObj; - } - if (! (ep->flags & EJS_FLAGS_EXIT)) { - if (! ep->gotException) { - ejsMemoryError(ep); - } - } - ejsFreeVar(ep, thisObj); - return 0; - } - - mprAssert(ejsBlockInUse(thisObj)); - - return thisObj; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct CallCons { - EjsVar *subClassConstructor, *subClass, *method; -} CallCons; - -/* - * Create a new object and call all required constructors. - */ - -static int callConstructor(Ejs *ep, EjsVar *thisObj, EjsVar *baseClass, - MprArray *args) -{ - CallCons *sp; - int state; - - if ((sp = pushFrame(ep, sizeof(CallCons))) == 0) { - return EJS_STATE_ERR; - } - - mprAssert(baseClass); - mprAssert(baseClass->objectState); - - state = 0; - - /* - * method will be null if there is no constructor for this class - */ - sp->method = ejsGetPropertyAsVar(ep, baseClass, - baseClass->objectState->className); - - if (sp->method == 0 || !ejsVarIsMethod(sp->method) || - !sp->method->callsSuper) { - /* - * Invoke base class constructors in reverse order (RECURSIVE) - */ - sp->subClass = baseClass->objectState->baseClass; - if (sp->subClass) { - - /* - * Note that the Object class does not have a constructor for - * speed. Construction for the base Object is done via - * ejsCreateObj above. The code below will invoke constructors - * in the right order (bottom up) via recursion. MOB -- need to - * scan for super() MOB -- Bug. Fails poorly if no constructor. - * Should allows this and invoke a default constructor. - */ - sp->subClassConstructor = ejsGetPropertyAsVar(ep, sp->subClass, - sp->subClass->objectState->className); - - if (sp->subClassConstructor) { - - if (callConstructor(ep, thisObj, sp->subClass, 0) < 0) { - if (! ep->gotException) { - ejsMemoryError(ep); - } - goto err; - } - } - } - } - - if (sp->method) { - /* - * Finally, invoke the constructor for this class itself. - */ - state = runMethod(ep, thisObj, sp->method, - baseClass->objectState->className, args); - } - -done: - popFrame(ep, sizeof(CallCons)); - return state; - -err: - state = EJS_STATE_ERR; - goto done; -} - -/******************************************************************************/ -/* - * Create a new object and call all required constructors using string args. - * MOB -- would be good to parse constructorArgs for "," and break into - * separate args. - * Returned object is not yet collectable. Will have alive bit cleared. - */ - -EjsVar *ejsCreateObj(Ejs *ep, EjsVar *obj, const char *className, - const char *constructorArgs) -{ - MprArray *args; - EjsVar *newp, *vp; - - args = mprCreateItemArray(ep, 0, 0); - if (args == 0) { - return 0; - } - - if (constructorArgs && *constructorArgs) { - vp = ejsCreateStringVarInternal(EJS_LOC_ARGS(ep), constructorArgs); - - if (mprAddItem(args, vp) < 0) { - mprFree(args); - return 0; - } - } - - newp = ejsCreateObjUsingArgv(ep, obj, className, args); - - ejsFreeMethodArgs(ep, args); - - mprAssert(! ejsObjIsCollectable(newp)); - mprAssert(ejsBlockInUse(newp)); - - return newp; -} - -/******************************************************************************/ - -static int callStringCMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, - EjsVar *prototype) -{ - EjsVar **argValues; - MprArray *actualArgs; - char **argBuf, *str; - int i, rc; - - actualArgs = proc->args; - argValues = (EjsVar**) actualArgs->items; - - if (actualArgs->length > 0) { - argBuf = mprAlloc(ep, actualArgs->length * sizeof(char*)); - for (i = 0; i < actualArgs->length; i++) { - str = ejsVarToString(ep, argValues[i]); - /* MOB rc */ - argBuf[i] = mprStrdup(ep, str); - } - } else { - argBuf = 0; - } - - /* - * Call the method depending on the various handle flags - */ - ep->userData = prototype->cMethodWithStrings.userData; - if (prototype->flags & EJS_ALT_HANDLE) { - /* - * Used by the AppWeb GaCompat module. The alt handle is set to the - * web server request struct - */ - rc = ((EjsAltStringCMethod) - prototype->cMethodWithStrings.fn) - (ep, ep->altHandle, obj, actualArgs->length, argBuf); - - } else if (prototype->flags & EJS_PRIMARY_HANDLE) { - /* - * Used by ESP. The primary handle is set to the esp struct - */ - rc = (prototype->cMethodWithStrings.fn)(ep->primaryHandle, - obj, actualArgs->length, argBuf); - - } else { - /* - * Used EJS for the standard procs - */ - rc = (prototype->cMethodWithStrings.fn)(ep, obj, actualArgs->length, - argBuf); - } - - if (actualArgs->length > 0) { - for (i = 0; i < actualArgs->length; i++) { - mprFree(argBuf[i]); - } - mprFree(argBuf); - } - ep->userData = 0; - - return rc; -} - -/******************************************************************************/ - -static int callCMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, EjsVar *prototype) -{ - EjsVar **argValues; - MprArray *actualArgs; - int rc; - - actualArgs = proc->args; - argValues = (EjsVar**) actualArgs->items; - - ep->userData = prototype->cMethod.userData; - - /* - * Call the method depending on the various handle flags - * Sometimes cMethod.fn is NULL if there is no constructor for - * an object. - */ - if (prototype->flags & EJS_ALT_HANDLE) { - /* - * Use by the GaCompat module. The alt handle is set to the - * web server request struct - */ - rc = ((EjsAltCMethod) prototype->cMethod.fn) - (ep, ep->altHandle, obj, actualArgs->length, argValues); - - } else if (prototype->flags & EJS_PRIMARY_HANDLE) { - /* - * Used by ESP. The primary handle is set to the esp struct - */ - rc = (prototype->cMethod.fn) - (ep->primaryHandle, obj, actualArgs->length, argValues); - - } else { - /* - * Used EJS for the standard procs - */ - rc = (prototype->cMethod.fn)(ep, obj, actualArgs->length, argValues); - } - - ep->userData = 0; - - return rc; -} - -/******************************************************************************/ -/* - * Local vars - */ - -typedef struct CallMethod { - MprArray *formalArgs, *actualArgs; - EjsVar *arguments, *callee, **argValues; - char **argNames, buf[16]; - int i, argumentsObj; -} CallMethod; - - -static int callMethod(Ejs *ep, EjsVar *obj, EjsProc *proc, EjsVar *prototype) -{ - CallMethod *sp; - int i; - - if ((sp = pushFrame(ep, sizeof(CallMethod))) == 0) { - return EJS_STATE_ERR; - } - - sp->arguments = 0; - sp->callee = 0; - - sp->actualArgs = proc->args; - sp->argValues = (EjsVar**) sp->actualArgs->items; - sp->formalArgs = prototype->method.args; - sp->argNames = (char**) sp->formalArgs->items; - - /* - * Only create arguments and callee if the function actually uses them - */ - sp->argumentsObj = 0; - if (strstr(prototype->method.body, "arguments") != 0) { - sp->argumentsObj++; - - /* - * Create the arguments and callee variables - * MOB -- should we make real arrays here ? YES - */ - sp->arguments = ejsCreateSimpleObj(ep, "Object"); - ejsSetVarName(ep, sp->arguments, "arguments"); - mprAssert(! ejsObjIsCollectable(sp->arguments)); - - sp->callee = ejsCreateSimpleObj(ep, "Object"); - ejsSetVarName(ep, sp->callee, "callee"); - mprAssert(! ejsObjIsCollectable(sp->callee)); - - /* - * Overwrite the length property - */ - ejsSetPropertyToInteger(ep, sp->arguments, "length", - sp->actualArgs->length); - ejsSetPropertyToInteger(ep, sp->callee, "length", - sp->formalArgs->length); - } - - /* - * Define all the agruments to be set to the actual parameters - */ - for (i = 0; i < sp->formalArgs->length; i++) { - if (i >= sp->actualArgs->length) { - /* MOB -- return code */ - ejsCreateProperty(ep, ep->local, sp->argNames[i]); - - } else { - /* MOB -- return code */ - ejsSetProperty(ep, ep->local, sp->argNames[i], sp->argValues[i]); - } - } - - if (sp->argumentsObj) { - for (i = 0; i < sp->actualArgs->length; i++) { - mprItoa(sp->buf, sizeof(sp->buf), i); - ejsSetProperty(ep, sp->arguments, sp->buf, sp->argValues[i]); - } - - ejsSetPropertyAndFree(ep, sp->arguments, "callee", sp->callee); - ejsSetPropertyAndFree(ep, ep->local, "arguments", sp->arguments); - } - - /* - * Actually run the method - */ - - i = ejsEvalScript(ep, prototype->method.body, 0); - - popFrame(ep, sizeof(CallMethod)); - return i; -} - -/******************************************************************************/ -/* - * Run a method. Obj is set to "this" object. MethodName must exist in it - * or in a sub class. - */ - -int ejsRunMethod(Ejs *ep, EjsVar *obj, const char *methodName, MprArray *args) -{ - EjsProperty *pp; - EjsProc proc, *saveProc; - int rc; - - mprAssert(obj); - mprAssert(methodName && *methodName); - - pp = ejsGetProperty(ep, obj, methodName); - if (pp == 0) { - /* MOB -- this should be all in some common accessor routine */ - pp = ejsGetProperty(ep, ep->local, methodName); - if (pp == 0) { - pp = ejsGetProperty(ep, ep->global, methodName); - if (pp == 0) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Undefined method \"%s\"", methodName); - return MPR_ERR_NOT_FOUND; - } - } - } - - saveProc = ep->proc; - ep->proc = &proc; - - memset(&proc, 0, sizeof(EjsProc)); - - ejsClearVar(ep, ep->result); - - /* MOB -- if closures are going to work, we need to have proc be an - Object and let the GC look after it */ - - proc.fn = &pp->var; - if (proc.fn == 0 || proc.fn->type == EJS_TYPE_UNDEFINED) { - ep->proc = saveProc; - return MPR_ERR_NOT_FOUND; - } - - proc.procName = mprStrdup(ep, methodName); - if (args == 0) { - proc.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); - } else { - proc.args = args; - } - - rc = evalMethod(ep, obj, &proc, 0); - - if (args) { - proc.args = 0; - } - freeProc(ep, &proc); - - ep->proc = saveProc; - - return rc; -} - -/******************************************************************************/ -/* - * Run a method. Obj is set to "this" object. MethodName must exist in it - * or in a sub class. - */ - -int ejsRunMethodCmd(Ejs *ep, EjsVar *obj, const char *methodName, - const char *cmdFmt, ...) -{ - MprArray *args; - va_list cmdArgs; - char *buf, *arg, *cp; - int rc; - - mprAssert(methodName && *methodName); - mprAssert(cmdFmt && *cmdFmt); - - va_start(cmdArgs, cmdFmt); - mprAllocVsprintf(MPR_LOC_ARGS(ep), &buf, 0, cmdFmt, cmdArgs); - va_end(cmdArgs); - - args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); - - for (arg = cp = buf; cp && *cp; cp++) { - if (*cp == ',') { - *cp = 0; - mprAddItem(args, ejsParseVar(ep, arg, 0)); - arg = cp + 1; - } - } - if (cp > arg) { - mprAddItem(args, ejsParseVar(ep, arg, 0)); - } - - rc = ejsRunMethod(ep, obj, methodName, args); - - ejsFreeMethodArgs(ep, args); - mprFree(buf); - - return rc; -} - -/******************************************************************************/ -/* - * Run a method. Obj is set to "this" object. - */ - -static int runMethod(Ejs *ep, EjsVar *thisObj, EjsVar *method, - const char *methodName, MprArray *args) -{ - EjsProc proc, *saveProc; - int rc; - - mprAssert(thisObj); - mprAssert(method); - - saveProc = ep->proc; - ep->proc = &proc; - - memset(&proc, 0, sizeof(EjsProc)); - - ejsClearVar(ep, ep->result); - - /* MOB -- if closures are going to work, we need to have proc be an - Object and let the GC look after it */ - - proc.fn = method; - if (proc.fn == 0 || proc.fn->type == EJS_TYPE_UNDEFINED) { - ep->proc = saveProc; - return MPR_ERR_NOT_FOUND; - } - - proc.procName = mprStrdup(ep, methodName); - if (args == 0) { - proc.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); - } else { - proc.args = args; - } - - rc = evalMethod(ep, thisObj, &proc, 0); - - if (args) { - proc.args = 0; - } - freeProc(ep, &proc); - - ep->proc = saveProc; - - return rc; -} - -/******************************************************************************/ -/* - * Find which object contains the property given the current context. - * We call this when there is no explicit object and the object must be - * determined by the context. - */ - -static EjsVar *pickSpace(Ejs *ep, int state, const char *property, int flags) -{ - EjsVar *obj; - - mprAssert(ep); - mprAssert(property && *property); - - /* MOB - this is ugly and the logic is confused */ - - if (flags & EJS_FLAGS_GLOBAL) { - obj = ep->global; - - } else if (state == EJS_STATE_DEC || flags & EJS_FLAGS_LOCAL) { - obj = ep->local; - - } else { - /* First look local, then this and finally global */ - - if (ejsGetSimpleProperty(ep, ep->local, property)) { - obj = ep->local; - - } else if (ep->thisObject && - findProperty(ep, ep->thisObject, property, flags)) { - obj = ep->thisObject; - - } else { -#if EJS_ECMA_STND - obj = ep->global; -#else - if (flags & EJS_FLAGS_EXE && - !findProperty(ep, ep->global, property, flags)) { - obj = ep->local; - } else { - obj = ep->global; - } -#endif - } - } - return obj; -} - -/******************************************************************************/ -/* - * Find an object property given a object and a property name. We - * intelligently look in the local and global namespaces depending on - * our state. If not found in local or global, try base classes for method - * names only. Returns the property or NULL. - * MOB -- need to rework this API. - */ - -static EjsProperty *searchSpacesForProperty(Ejs *ep, int state, EjsVar *obj, - char *property, int flags) -{ - EjsProperty *pp; - - if (obj) { - return findProperty(ep, obj, property, flags); - } - - /* MOB -- really should have a search stack */ - - pp = findProperty(ep, ep->local, property, flags); - if (pp == 0 && state != EJS_STATE_DEC) { - - if (ep->thisObject) { - pp = findProperty(ep, ep->thisObject, property, flags); - } - if (pp == 0) { - pp = findProperty(ep, ep->global, property, flags); - } - } - return pp; -} - -/******************************************************************************/ -/* - * Search an object and its base classes to find an object given an object - * an a property name. If not an assignment (LHS), then follow base classes. - * Otherwise, just look in the specified object. - */ - -static EjsProperty *findProperty(Ejs *ep, EjsVar *op, const char *property, - int flags) -{ - /* MOB -- NEW. Remove when EXE fixes are in. */ - if (! (flags & EJS_FLAGS_EXE) && op->type == EJS_TYPE_UNDEFINED) { - return 0; - } - - if (flags & EJS_FLAGS_LHS) { - return ejsGetPropertyPtr(ejsGetSimpleProperty(ep, op, property)); - - } else { - /* - * Follow base classes - */ - return ejsGetPropertyPtr(ejsGetProperty(ep, op, property)); - } -} - -/******************************************************************************/ -/* - * Update result - */ - -static void updateResult(Ejs *ep, int state, int flags, EjsVar *vp) -{ - if (flags & EJS_FLAGS_EXE && state != EJS_STATE_DEC) { - ejsClearVar(ep, ep->result); - if (vp) { - ejsWriteVar(ep, ep->result, vp, EJS_SHALLOW_COPY); - ejsSetVarName(ep, ep->result, vp->propertyName); - } - } -} - -/******************************************************************************/ -/* - * Append to the pointer value - */ - -int ejsStrcat(Ejs *ep, EjsVar *dest, EjsVar *src) -{ - char *oldBuf, *buf, *str; - int oldLen, newLen, len; - - mprAssert(dest); - mprAssert(ejsVarIsString(src)); - - if (ejsVarIsValid(dest)) { - - if (! ejsVarIsString(dest)) { - /* Bad type for dest */ - return -1; - } - - if (! ejsVarIsString(src)) { - str = ejsVarToString(ep, src); - if (str == 0) { - return -1; - } - len = strlen(str); - - } else { - str = src->string; - len = src->length; - } - - oldBuf = dest->string; - oldLen = dest->length; - newLen = oldLen + len + 1; - - if (newLen < MPR_SLAB_STR_MAX) { - buf = oldBuf; - } else { - buf = mprRealloc(ep, oldBuf, newLen); - if (buf == 0) { - return -1; - } - dest->string = buf; - } - memcpy(&buf[oldLen], str, len); - dest->length += len; - - } else { - ejsWriteVarAsString(ep, dest, src->string); - } - return 0; -} - -/******************************************************************************/ -/* - * Exit the script - */ - -void ejsExit(Ejs *ep, int status) -{ - ep->scriptStatus = status; - ep->flags |= EJS_FLAGS_EXIT; -} - -/******************************************************************************/ -/* - * Free an argument list - */ - -static void freeProc(Ejs *ep, EjsProc *proc) -{ - if (proc->args) { - ejsFreeMethodArgs(ep, proc->args); - } - - if (proc->procName) { - mprFree(proc->procName); - proc->procName = NULL; - } -} - -/******************************************************************************/ - -void ejsFreeMethodArgs(Ejs *ep, MprArray *args) -{ - int i; - - for (i = args->length - 1; i >= 0; i--) { - ejsFreeVar(ep, args->items[i]); - mprRemoveItemByIndex(args, i); - } - mprFree(args); -} - -/******************************************************************************/ -/* - * This method removes any new lines. Used for else cases, etc. - */ - -static void removeNewlines(Ejs *ep, int state) -{ - int tid; - - do { - tid = ejsLexGetToken(ep, state); - } while (tid == EJS_TOK_NEWLINE); - - ejsLexPutbackToken(ep, tid, ep->token); -} - -/******************************************************************************/ - -static int getNextNonSpaceToken(Ejs *ep, int state) -{ - int tid; - - do { - tid = ejsLexGetToken(ep, state); - } while (tid == EJS_TOK_NEWLINE); - return tid; -} - -/******************************************************************************/ - -int ejsGetFlags(Ejs *ep) -{ - return ep->flags; -} - -/******************************************************************************/ - -bool ejsIsExiting(Ejs *ep) -{ - return (ep->flags & EJS_FLAGS_EXIT) ? 1: 0; -} - -/******************************************************************************/ - -void ejsClearExiting(Ejs *ep) -{ - ep->flags &= ~EJS_FLAGS_EXIT; -} - -/******************************************************************************/ - -static EjsInput *getInputStruct(Ejs *ep) -{ - EjsInput *input; - - if (ep->inputList) { - input = ep->inputList; - ep->inputList = input->nextInput; - - } else { - input = mprAlloc(ep, sizeof(EjsInput)); - } - return input; -} - -/******************************************************************************/ - -static void freeInputStruct(Ejs *ep, EjsInput *input) -{ - input->nextInput = ep->inputList; - ep->inputList = input; -} - -/******************************************************************************/ - -static void *pushFrame(Ejs *ep, int size) -{ - /* - * Grow down stack - */ - ep->stkPtr -= size; - if (ep->stkPtr < ep->stack) { - mprError(ep, MPR_LOC, "Exceeded parse stack"); - return 0; - } - return ep->stkPtr; -} - -/******************************************************************************/ - -static void *popFrame(Ejs *ep, int size) -{ - ep->stkPtr += size; - if (ep->stkPtr > &ep->stack[EJS_MAX_STACK]) { - mprError(ep, MPR_LOC, "Over poped parse stack"); - return 0; - } - return ep->stkPtr; -} - -/******************************************************************************/ -#else -void ejsParserDummy() {} - -/******************************************************************************/ -#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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.c b/source4/lib/appweb/ejs-2.0/ejs/ejsVar.c deleted file mode 100644 index 1f8e9266a3..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.c +++ /dev/null @@ -1,4033 +0,0 @@ -/** - * @file ejsVar.c - * @brief Mbedthis Portable Runtime Universal Variable Type - */ - -/* - * @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 - */ - -/******************************* Documentation ********************************/ - -/* - * This module is NOT multithreaded. - * - * Properties are variables that are stored in an object type variable. - * Properties can be primitive data types, other objects or methods. - * Properties are indexed by a character name. - */ - -/********************************** Includes **********************************/ - -#include "ejs.h" - -/***************************** Forward Declarations ***************************/ - -static EjsProperty *allocProperty(Ejs *ep, EjsVar *op, const char *property, - int propertyIndex, EjsProperty *last); -static EjsVar *copyVar(EJS_LOC_DEC(ep, loc), EjsVar *dest, - const EjsVar *src, EjsCopyDepth copyDepth); -static EjsObj *createObj(EJS_LOC_DEC(ep, loc)); -static char *getNextVarToken(char **next, char *tokBuf, int tokBufLen); -static int hash(const char *property); -static void unlinkProperty(EjsObj *obj, EjsPropLink *propLink); -static void linkPropertyBefore(EjsObj *obj, EjsPropLink *at, - EjsPropLink *propLink); -static int sortAllProperties(Ejs *ep, EjsProperty *p1, - EjsProperty *p2, const char *propertyName, int order); -static int sortByProperty(Ejs *ep, EjsProperty *p1, EjsProperty *p2, - const char *propertyName, int order); -static int dupString(MPR_LOC_DEC(ctx, loc), uchar **dest, - const void *src, int nbytes); -#if UNUSED && KEEP -static void linkPropertyAfter(EjsObj *obj, EjsPropLink *at, - EjsPropLink *propLink); -#endif - -static EjsProperty *hashLookup(EjsObj *obj, const char *property, - int *propertyIndex, EjsProperty **hashTail); - -/******************************************************************************/ -/********************************** Var Routines ******************************/ -/******************************************************************************/ - -EjsType ejsGetVarType(EjsVar *vp) -{ - mprAssert(vp); - - return vp->type; -} - -/******************************************************************************/ - -void ejsFreeVar(Ejs *ep, EjsVar *vp) -{ - if (vp) { - ejsClearVar(ep, vp); - ejsFree(ep, vp, EJS_SLAB_VAR); - } -} - -/******************************************************************************/ -#if UNUSED -/* - * Clear the value by freeing any allocated data. This will release objects - * so that later garbage collection can reclaim storage if there are no other - * object references. - */ - -void ejsZeroVar(Ejs *ep, EjsVar *vp) -{ - vp->type = EJS_TYPE_UNDEFINED; - vp->objectState = 0; - vp->method.body = 0; - vp->method.args = 0; - vp->callsSuper = 0; - vp->ptr.destructor = 0; - vp->allocatedData = 0; -} - -#endif -/******************************************************************************/ -/* - * Clear the value by freeing any allocated data. This will release objects - * so that later garbage collection can reclaim storage if there are no other - * object references. - */ - -void ejsClearVar(Ejs *ep, EjsVar *vp) -{ - MprArray *argList; - int i; - - mprAssert(vp); - mprAssert(ep); - - if (! vp->allocatedData) { - vp->type = EJS_TYPE_UNDEFINED; - return; - } - if (vp->type == EJS_TYPE_UNDEFINED) { - return; - } - - switch (vp->type) { - default: - break; - - case EJS_TYPE_STRING: - mprFree(vp->string); - vp->string = 0; - break; - - case EJS_TYPE_OBJECT: - /* - * Set the "alive" bit so that the GC will cleanup if no - * other references. - */ - if (vp->objectState) { - vp->objectState->alive = 1; - } - vp->objectState = 0; - break; - - case EJS_TYPE_METHOD: - argList = vp->method.args; - /* - * MOB OPT -- should be able to do just one mprFree(vp->method.args) - */ - mprFree(vp->method.body); - if (argList) { - for (i = 0; i < argList->length; i++) { - mprFree(argList->items[i]); - } - mprFree(vp->method.args); - } - vp->method.args = 0; - vp->method.body = 0; - vp->callsSuper = 0; - break; - - case EJS_TYPE_PTR: - if (vp->ptr.destructor) { - (vp->ptr.destructor)(ep, vp); - } - break; - } - - vp->type = EJS_TYPE_UNDEFINED; - vp->allocatedData = 0; -} - -/******************************************************************************/ -/* - * Initialize an undefined value. - */ - -EjsVar *ejsCreateUndefinedVar(Ejs *ep) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_UNDEFINED; - } - return vp; -} - -/******************************************************************************/ -/* - * Initialize an null value. - */ - -EjsVar *ejsCreateNullVar(Ejs *ep) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_NULL; - } - return vp; -} - -/******************************************************************************/ - -EjsVar *ejsCreateBoolVar(Ejs *ep, int value) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_BOOL; - vp->boolean = value; - } - return vp; -} - -/******************************************************************************/ -/* - * Initialize a C method. - */ - -EjsVar *ejsCreateCMethodVar(Ejs *ep, EjsCMethod fn, void *userData, int flags) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_CMETHOD; - vp->cMethod.fn = fn; - vp->cMethod.userData = userData; - vp->flags = flags; - } - return vp; -} - -/******************************************************************************/ -/* - * Initialize a C method. - */ - -EjsVar *ejsCreateStringCMethodVar(Ejs *ep, EjsStringCMethod fn, - void *userData, int flags) -{ - EjsVar *vp; - - mprAssert(ep); - mprAssert(fn); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_STRING_CMETHOD; - vp->cMethodWithStrings.fn = fn; - vp->cMethodWithStrings.userData = userData; - vp->flags = flags; - } - return vp; -} - -/******************************************************************************/ -/* - * Initialize an opaque pointer. - */ - -EjsVar *ejsCreatePtrVar(Ejs *ep, void *ptr, EjsDestructor destructor) -{ - EjsVar *vp; - - mprAssert(ep); - mprAssert(ptr); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_PTR; - vp->ptr.userPtr = ptr; - vp->ptr.destructor = destructor; - vp->allocatedData = 1; - } - return vp; -} - -/******************************************************************************/ -#if BLD_FEATURE_FLOATING_POINT -/* - * Initialize a floating value. - */ - -EjsVar *ejsCreateFloatVar(Ejs *ep, double value) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_FLOAT; - vp->floating = value; - } - return vp; -} - -#endif -/******************************************************************************/ -/* - * Initialize an integer value. - */ - -EjsVar *ejsCreateIntegerVar(Ejs *ep, int value) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_INT; - vp->integer = value; - } - return vp; -} - -/******************************************************************************/ -#if BLD_FEATURE_INT64 -/* - * Initialize a 64-bit integer value. - */ - -EjsVar *ejsCreateInteger64Var(Ejs *ep, int64 value) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_INT64; - vp->integer64 = value; - } - return vp; -} - -#endif /* BLD_FEATURE_INT64 */ -/******************************************************************************/ -/* - * Initialize an number variable. Type is defined by configure. - */ - -EjsVar *ejsCreateNumberVar(Ejs *ep, EjsNum value) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - mprAssert(vp); - - if (vp) { - vp->type = BLD_FEATURE_NUM_TYPE_ID; -#if BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_INT64 - vp->integer64 = value; -#elif BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_FLOAT - vp->float = value; -#else - vp->integer = value; -#endif - } - return vp; -} - -/******************************************************************************/ -/* - * Initialize a (bare) JavaScript method. args and body can be null. - */ - -EjsVar *ejsCreateMethodVar(Ejs *ep, const char *body, MprArray *args, int flags) -{ - EjsVar *vp; - int i; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - mprAssert(vp); - - if (vp == 0) { - return 0; - } - - vp->type = EJS_TYPE_METHOD; - - vp->allocatedData = 1; - - vp->method.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); - if (vp->method.args == 0) { - mprAssert(vp->method.args); - ejsFreeVar(ep, vp); - return 0; - } - - if (args) { - for (i = 0; i < args->length; i++) { - mprAddItem(vp->method.args, - mprStrdup(vp->method.args, mprGetItem(args, i))); - } - } - vp->method.body = mprStrdup(vp->method.args, body); - - if (vp->method.body == 0) { - ejsFreeVar(ep, vp); - return 0; - } - vp->flags = flags; - - return vp; -} - -/******************************************************************************/ -/* - * Initialize an object variable. - */ - -EjsVar *ejsCreateObjVarInternal(EJS_LOC_DEC(ep, loc)) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_PASS(ep, loc)); - mprAssert(vp); - - if (vp) { - vp->type = EJS_TYPE_OBJECT; - vp->objectState = createObj(EJS_LOC_PASS(ep, loc)); - if (vp->objectState == 0) { - ejsFreeVar(ep, vp); - return 0; - } - vp->allocatedData = 1; - } - return vp; -} - -/******************************************************************************/ -/* - * Initialize a string value. - */ - -EjsVar *ejsCreateStringVarInternal(EJS_LOC_DEC(ep, loc), const char *value) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_PASS(ep, loc)); - mprAssert(vp); - - if (vp) { - vp->type = EJS_TYPE_STRING; - vp->string = mprStrdupInternal(EJS_LOC_PASS(ep, loc), value); - if (vp->string == 0) { - ejsFreeVar(ep, vp); - return 0; - } - vp->length = strlen(vp->string); - vp->allocatedData = 1; - } - return vp; -} - -/******************************************************************************/ -/* - * Initialize a binary string value. - */ - -EjsVar *ejsCreateBinaryStringVar(Ejs *ep, const uchar *value, int len) -{ - EjsVar *vp; - - mprAssert(ep); - - vp = ejsAllocVar(EJS_LOC_ARGS(ep)); - if (vp) { - vp->type = EJS_TYPE_STRING; - vp->length = dupString(MPR_LOC_ARGS(ep), &vp->ustring, value, len); - if (vp->length < 0) { - ejsFreeVar(ep, vp); - return 0; - } - vp->allocatedData = 1; - } - return vp; -} - -/******************************************************************************/ - -void ejsSetClassName(Ejs *ep, EjsVar *vp, const char *name) -{ - EjsObj *obj; - - if (vp == 0 || !ejsVarIsObject(vp) || vp->objectState == 0) { - mprAssert(0); - return; - } - obj = vp->objectState; - - if (obj->className) { - mprFree(obj->className); - } - obj->className = mprStrdup(ep, name); -} - -/******************************************************************************/ - -EjsVar *ejsDupVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *src, - EjsCopyDepth copyDepth) -{ - EjsVar *vp; - - vp = ejsAllocVar(EJS_LOC_PASS(ep, loc)); - if (vp == 0) { - return 0; - } - - vp->type = EJS_TYPE_UNDEFINED; - - return copyVar(EJS_LOC_PASS(ep, loc), vp, src, copyDepth); -} - -/******************************************************************************/ -/* - * Set a var to a new value - */ - -EjsVar *ejsWriteVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *dest, - const EjsVar *src, EjsCopyDepth copyDepth) -{ - mprAssert(dest); - mprAssert(src); - - return copyVar(EJS_LOC_PASS(ep, loc), dest, src, copyDepth); -} - -/******************************************************************************/ -/* - * Set a var using a new bool value - */ - -EjsVar *ejsWriteVarAsBoolean(Ejs *ep, EjsVar *dest, int value) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_TYPE_BOOL; - dest->boolean = value; - dest->allocatedData = 0; - dest->flags = 0; - - return dest; -} - -/******************************************************************************/ -/* - * Set a var using a new C Method - */ - -EjsVar *ejsWriteVarAsCMethod(Ejs *ep, EjsVar *dest, EjsCMethod fn, - void *userData, int flags) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_TYPE_CMETHOD; - dest->cMethod.fn = fn; - dest->cMethod.userData = userData; - dest->flags = flags; - dest->allocatedData = 0; - - return dest; -} - -/******************************************************************************/ -#if BLD_FEATURE_FLOATING_POINT -/* - * Set a var using a new float value - */ - -EjsVar *ejsWriteVarAsFloat(Ejs *ep, EjsVar *dest, double value) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_TYPE_FLOAT; - dest->floating = value; - dest->allocatedData = 0; - dest->flags = 0; - - return dest; -} - -#endif -/******************************************************************************/ -/* - * Set a var using a new integer value - */ - -EjsVar *ejsWriteVarAsInteger(Ejs *ep, EjsVar *dest, int value) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_TYPE_INT; - dest->integer = value; - dest->allocatedData = 0; - dest->flags = 0; - - return dest; -} - -/******************************************************************************/ -#if BLD_FEATURE_INT64 -/* - * Set a var using a new integer value - */ - -EjsVar *ejsWriteVarAsInteger64(Ejs *ep, EjsVar *dest, int64 value) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_TYPE_INT64; - dest->integer64 = value; - dest->allocatedData = 0; - dest->flags = 0; - - return dest; -} - -#endif -/******************************************************************************/ -/* - * Set a var using a new Method - */ - -EjsVar *ejsWriteVarAsMethod(Ejs *ep, EjsVar *dest, const char *body, - MprArray *args) -{ - EjsVar **srcArgs, *arg; - int i; - - mprAssert(ep); - mprAssert(dest); - mprAssert(body); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->method.args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); - if (dest->method.args == 0) { - return 0; - } - - dest->type = EJS_TYPE_METHOD; - - if (args) { - srcArgs = (EjsVar**) args->items; - for (i = 0; i < args->length; i++) { - arg = ejsDupVar(ep, srcArgs[i], EJS_SHALLOW_COPY); - if (arg == 0) { - return 0; - } - if (mprAddItem(dest->method.args, arg) < 0) { - return 0; - } - } - } - - dest->method.body = mprStrdup(dest->method.args, body); - if (dest->method.body == 0) { - return 0; - } - - dest->allocatedData = 1; - dest->flags = 0; - - return dest; -} - -/******************************************************************************/ -/* - * Set a var to null - */ - -EjsVar *ejsWriteVarAsNull(Ejs *ep, EjsVar *dest) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_TYPE_NULL; - dest->allocatedData = 0; - dest->flags = 0; - - return dest; -} - -/******************************************************************************/ -/* - * Set a var using a new number value - */ - -EjsVar *ejsWriteVarAsNumber(Ejs *ep, EjsVar *dest, EjsNum value) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_NUM_VAR; - dest->ejsNumber = value; - dest->allocatedData = 0; - dest->flags = 0; - - return dest; -} - -/******************************************************************************/ -/* - * Set a var using a new C Method - */ - -EjsVar *ejsWriteVarAsStringCMethod(Ejs *ep, EjsVar *dest, EjsStringCMethod fn, - void *userData, int flags) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_TYPE_CMETHOD; - dest->cMethodWithStrings.fn = fn; - dest->cMethodWithStrings.userData = userData; - dest->flags = flags; - dest->allocatedData = 0; - - return dest; -} - -/******************************************************************************/ -/* - * Set a var using a new string value - */ - -EjsVar *ejsWriteVarAsStringInternal(EJS_LOC_DEC(ep, loc), EjsVar *dest, - const char *value) -{ - mprAssert(dest); - mprAssert(value); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->string = mprStrdupInternal(EJS_LOC_PASS(ep, loc), value); - if (dest->string == 0) { - return 0; - } - - dest->length = strlen(dest->string); - - dest->type = EJS_TYPE_STRING; - dest->allocatedData = 1; - dest->flags = 0; - - return dest; -} - -/******************************************************************************/ -/* - * Set a var using a new string value - */ - -EjsVar *ejsWriteVarAsBinaryString(Ejs *ep, EjsVar *dest, const uchar *value, - int len) -{ - mprAssert(dest); - mprAssert(value); - - ejsClearVar(ep, dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->length = dupString(MPR_LOC_ARGS(ep), &dest->ustring, value, len); - if (dest->length < 0) { - return 0; - } - - dest->type = EJS_TYPE_STRING; - dest->allocatedData = 1; - dest->flags = 0; - - return dest; -} - -/******************************************************************************/ -/* - * Set a var to undefined - */ - -EjsVar *ejsWriteVarAsUndefined(Ejs *ep, EjsVar *dest) -{ - mprAssert(dest); - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->type = EJS_TYPE_UNDEFINED; - dest->allocatedData = 0; - dest->flags = 0; - - return dest; -} - -/******************************************************************************/ -/* - * Convert a value to a text based representation of its value - * If you provide a format, you MUST ensure you know the type. - * Caller must free the result. - */ - -char *ejsFormatVar(Ejs *ep, const char *fmt, EjsVar *vp) -{ - char *buf, *src, *value, *allocValue; - uchar *ubuf; - int len; - - buf = 0; - allocValue = 0; - value = 0; - - switch (vp->type) { - case EJS_TYPE_UNDEFINED: - value = "undefined"; - break; - - case EJS_TYPE_NULL: - value = "null"; - break; - - case EJS_TYPE_PTR: - if (fmt == NULL || *fmt == '\0') { - len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, - "[Opaque Pointer %p]", vp->ptr.userPtr); - } else { - len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, vp->ptr); - } - goto done; - - case EJS_TYPE_BOOL: - value = (vp->boolean) ? "true" : "false"; - break; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - if (fmt == NULL || *fmt == '\0') { - fmt = "%f"; - } - len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, vp->floating); - goto done; -#endif - - case EJS_TYPE_INT: - if (fmt == NULL || *fmt == '\0') { - fmt = "%d"; - } - mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, vp->integer); - goto done; - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - if (fmt == NULL || *fmt == '\0') { - fmt = "%Ld"; - } - mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, vp->integer64); - goto done; -#endif - - case EJS_TYPE_CMETHOD: - value = "[C Method]"; - break; - - case EJS_TYPE_STRING_CMETHOD: - value = "[C StringMethod]"; - break; - - case EJS_TYPE_METHOD: - value = ejsVarToString(ep, vp); - break; - - case EJS_TYPE_OBJECT: - value = ejsVarToString(ep, vp); - break; - - case EJS_TYPE_STRING: - src = vp->string; - mprAssert(src); - - if (fmt && *fmt && src) { - mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, src); - - } else if (src == NULL) { - buf = mprStrdup(ep, "null"); - - } else { - ubuf = (uchar*) buf; - if (dupString(MPR_LOC_ARGS(ep), &ubuf, src, vp->length) < 0) { - return mprStrdup(ep, ""); - } - buf = (char*) ubuf; - } - break; - - default: - mprAssert(0); - } - - if (fmt == NULL || *fmt == '\0') { - len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, "%s", value); - } else { - len = mprAllocSprintf(MPR_LOC_ARGS(ep), &buf, 0, fmt, value); - } - -done: - if (allocValue) { - mprFree(allocValue); - } - return buf; -} - -/******************************************************************************/ -/* - * Convert the variable to a boolean. Only for primitive types. - */ - -int ejsVarToBoolean(EjsVar *vp) -{ - mprAssert(vp); - - switch (vp->type) { - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - case EJS_TYPE_STRING_CMETHOD: - case EJS_TYPE_CMETHOD: - case EJS_TYPE_METHOD: - return 0; - - case EJS_TYPE_OBJECT: - return (vp->objectState != NULL); - - case EJS_TYPE_PTR: - return (vp->ptr.userPtr != NULL); - - case EJS_TYPE_BOOL: - return vp->boolean; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - return (vp->floating != 0 && !ejsIsNan(vp->floating)); -#endif - - case EJS_TYPE_INT: - return (vp->integer != 0); - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - return (vp->integer64 != 0); -#endif - - case EJS_TYPE_STRING: - return (vp->length > 0); -#if UNUSED - if (strcmp(vp->string, "true") == 0 || - strcmp(vp->string, "TRUE") == 0) { - return 1; - - } else if (strcmp(vp->string, "false") == 0 || - strcmp(vp->string, "FALSE") == 0) { - return 0; - - } else { - return atoi(vp->string); - } -#endif - } - - /* Not reached */ - return 0; -} - -/******************************************************************************/ -#if BLD_FEATURE_FLOATING_POINT -/* - * Convert the variable to a floating point number. Only for primitive types. - */ - -double ejsVarToFloat(EjsVar *vp) -{ - mprAssert(vp); - - switch (vp->type) { - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - case EJS_TYPE_STRING_CMETHOD: - case EJS_TYPE_CMETHOD: - case EJS_TYPE_METHOD: - case EJS_TYPE_OBJECT: - case EJS_TYPE_PTR: - return 0; - - case EJS_TYPE_BOOL: - return (vp->boolean) ? 1.0 : 0.0; - - case EJS_TYPE_FLOAT: - return vp->floating; - - case EJS_TYPE_INT: - return (double) vp->integer; - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - return (double) vp->integer64; -#endif - - case EJS_TYPE_STRING: - if (vp->length == 0) { - return 0.0; - } else { - return atof(vp->string); - } - } - - /* Not reached */ - return 0; -} - -#endif -/******************************************************************************/ -/* - * Convert the variable to an Integer type. Only works for primitive types. - */ - -int ejsVarToInteger(EjsVar *vp) -{ - mprAssert(vp); - - switch (vp->type) { - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - case EJS_TYPE_STRING_CMETHOD: - case EJS_TYPE_CMETHOD: - case EJS_TYPE_METHOD: - case EJS_TYPE_OBJECT: - return 0; - - case EJS_TYPE_BOOL: - return (vp->boolean) ? 1 : 0; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - if (ejsIsNan(vp->floating)) { - return 0; - } - return (int) vp->floating; -#endif - - case EJS_TYPE_INT: - return vp->integer; - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - return (int) vp->integer64; -#endif - - case EJS_TYPE_STRING: - if (vp->length == 0) { - return 0; - } else { - return ejsParseInteger(vp->string); - } - } - - /* Not reached */ - return 0; -} - -/******************************************************************************/ -#if BLD_FEATURE_INT64 -/* - * Convert the variable to an Integer64 type. Only works for primitive types. - */ - -int64 ejsVarToInteger64(EjsVar *vp) -{ - mprAssert(vp); - - switch (vp->type) { - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - case EJS_TYPE_STRING_CMETHOD: - case EJS_TYPE_CMETHOD: - case EJS_TYPE_METHOD: - case EJS_TYPE_OBJECT: - case EJS_TYPE_PTR: - return 0; - - case EJS_TYPE_BOOL: - return (vp->boolean) ? 1 : 0; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - if (ejsIsNan(vp->floating)) { - return 0; - } - return (int64) vp->floating; -#endif - - case EJS_TYPE_INT: - return vp->integer; - - case EJS_TYPE_INT64: - return vp->integer64; - - case EJS_TYPE_STRING: - if (vp->length == 0) { - return 0; - } else { - return ejsParseInteger64(vp->string); - } - } - - /* Not reached */ - return 0; -} - -#endif /* BLD_FEATURE_INT64 */ -/******************************************************************************/ -/* - * Convert the variable to a number type. Only works for primitive types. - */ - -EjsNum ejsVarToNumber(EjsVar *vp) -{ -#if BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_INT64 - return ejsVarToInteger64(vp); -#elif BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_FLOAT - return ejsVarToFloat(vp); -#else - return ejsVarToInteger(vp); -#endif -} - -/******************************************************************************/ -/* - * Convert a var to a string. Store the result in ep->castTemp. If allocated - * set ep->castAlloc to TRUE. Caller must NOT free the result. - */ - -char *ejsVarToString(Ejs *ep, EjsVar *vp) -{ - MprBuf *bp; - char numBuf[16]; - int len, i; - - if (ep->castAlloc) { - mprFree(ep->castTemp); - } - ep->castTemp = 0; - ep->castAlloc = 0; - - switch (vp->type) { - case EJS_TYPE_UNDEFINED: - ep->castTemp = "undefined"; - break; - - case EJS_TYPE_NULL: - ep->castTemp = "null"; - break; - - case EJS_TYPE_PTR: - len = mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0, - "[Opaque Pointer %p]", vp->ptr.userPtr); - ep->castAlloc = 1; - break; - - case EJS_TYPE_BOOL: - if (vp->boolean) { - ep->castTemp = "true"; - } else { - ep->castTemp = "false"; - } - break; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - len = mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0, - "%f", vp->floating); - ep->castAlloc = 1; - break; -#endif - - case EJS_TYPE_INT: - mprItoa(numBuf, sizeof(numBuf), vp->integer); - ep->castTemp = mprStrdup(ep, numBuf); - ep->castAlloc = 1; - break; - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - mprAllocSprintf(MPR_LOC_ARGS(ep), &ep->castTemp, 0, - "%Ld", vp->integer64); - ep->castAlloc = 1; - break; -#endif - - case EJS_TYPE_CMETHOD: - ep->castTemp = "[C Method]"; - break; - - case EJS_TYPE_STRING_CMETHOD: - ep->castTemp = "[C StringMethod]"; - break; - - case EJS_TYPE_METHOD: - bp = mprCreateBuf(ep, 0, 0); - mprPutStringToBuf(bp, "function ("); - for (i = 0; i < vp->method.args->length; i++) { - mprPutStringToBuf(bp, vp->method.args->items[i]); - if ((i + 1) < vp->method.args->length) { - mprPutStringToBuf(bp, ", "); - } - } - mprPutStringToBuf(bp, ") {"); - mprPutStringToBuf(bp, vp->method.body); - mprPutStringToBuf(bp, "}"); - mprAddNullToBuf(bp); - ep->castTemp = mprStealBuf(ep, bp); - ep->castAlloc = 1; - mprFree(bp); - break; - - case EJS_TYPE_OBJECT: - if (ejsRunMethod(ep, vp, "toString", 0) < 0) { - return mprStrdup(ep, "[object Object]"); - } - ep->castTemp = mprStrdup(ep, ep->result->string); - ep->castAlloc = 1; - break; - - case EJS_TYPE_STRING: - if (vp->string == 0) { - ep->castTemp = "null"; - } else { - ep->castTemp = vp->string; - } - break; - - default: - mprAssert(0); - } - - mprAssert(ep->castTemp); - return ep->castTemp; -} - -/******************************************************************************/ - -char *ejsVarToStringEx(Ejs *ep, EjsVar *vp, bool *alloc) -{ - char *str; - - mprAssert(alloc); - - str = ejsVarToString(ep, vp); - *alloc = ep->castAlloc; - ep->castAlloc = 0; - ep->castTemp = 0; - return str; -} - -/******************************************************************************/ -/* - * Parse a string based on formatting instructions and intelligently - * create a variable. - * - * Float format: [+|-]DIGITS][DIGITS][(e|E)[+|-]DIGITS] - */ - -EjsVar *ejsParseVar(Ejs *ep, const char *buf, EjsType preferredType) -{ - EjsType type; - const char *cp; - int isHex; - - mprAssert(buf); - - type = preferredType; - - if (preferredType == EJS_TYPE_UNDEFINED) { - isHex = 0; - if (*buf == '-' || *buf == '+') { - type = EJS_NUM_VAR; - - } else if (!isdigit((int) *buf)) { - if (strcmp(buf, "true") == 0 || strcmp(buf, "false") == 0) { - type = EJS_TYPE_BOOL; - } else { - type = EJS_TYPE_STRING; - } - - } else if (isdigit((int) *buf)) { - type = EJS_NUM_VAR; - cp = buf; - if (*cp && tolower(cp[1]) == 'x') { - cp = &cp[2]; - isHex = 1; - for (cp = buf; *cp; cp++) { - if (! isxdigit((int) *cp)) { - break; - } - } - } else { -#if BLD_FEATURE_FLOATING_POINT - /* Could be integer or float */ - for (cp = buf; *cp; cp++) { - if (! isdigit((int) *cp)) { - int c = tolower(*cp); - if (c == '.' || c == 'e' || c == 'f') { - type = EJS_TYPE_FLOAT; - break; - } - } - } -#endif - } - } - } - - switch (type) { - case EJS_TYPE_OBJECT: - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - case EJS_TYPE_PTR: - default: - break; - - case EJS_TYPE_BOOL: - return ejsCreateBoolVar(ep, ejsParseBoolean(buf)); - - case EJS_TYPE_INT: - return ejsCreateIntegerVar(ep, ejsParseInteger(buf)); - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - return ejsCreateInteger64Var(ep, ejsParseInteger64(buf)); -#endif - - case EJS_TYPE_STRING: - if (strcmp(buf, "null") == 0) { - return ejsCreateNullVar(ep); - - } else if (strcmp(buf, "undefined") == 0) { - return ejsCreateUndefinedVar(ep); - } - - return ejsCreateStringVar(ep, buf); - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - return ejsCreateFloatVar(ep, atof(buf)); -#endif - - } - return ejsCreateUndefinedVar(ep); -} - -/******************************************************************************/ -/* - * Convert the variable to a number type. Only works for primitive types. - */ - -bool ejsParseBoolean(const char *s) -{ - if (s == 0 || *s == '\0') { - return 0; - } - if (strcmp(s, "false") == 0 || strcmp(s, "FALSE") == 0) { - return 0; - } - return 1; -} - -/******************************************************************************/ -/* - * Convert the variable to a number type. Only works for primitive types. - */ - -EjsNum ejsParseNumber(const char *s) -{ -#if BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_INT64 - return ejsParseInteger64(s); -#elif BLD_FEATURE_NUM_TYPE_ID == EJS_TYPE_FLOAT - return ejsParseFloat(s); -#else - return ejsParseInteger(s); -#endif -} - -/******************************************************************************/ -#if BLD_FEATURE_INT64 -/* - * Convert the string buffer to an Integer64. - */ - -int64 ejsParseInteger64(const char *str) -{ - const char *cp; - int64 num64; - int radix, c, negative; - - mprAssert(str); - - cp = str; - num64 = 0; - negative = 0; - - if (*cp == '-') { - cp++; - negative = 1; - } else if (*cp == '+') { - cp++; - } - - /* - * Parse a number. Observe hex and octal prefixes (0x, 0) - */ - if (*cp != '0') { - /* - * Normal numbers (Radix 10) - */ - while (isdigit((int) *cp)) { - num64 = (*cp - '0') + (num64 * 10); - cp++; - } - } else { - cp++; - if (tolower(*cp) == 'x') { - cp++; - radix = 16; - while (*cp) { - c = tolower(*cp); - if (isdigit(c)) { - num64 = (c - '0') + (num64 * radix); - } else if (c >= 'a' && c <= 'f') { - num64 = (c - 'a' + 10) + (num64 * radix); - } else { - break; - } - cp++; - } - - } else{ - radix = 8; - while (*cp) { - c = tolower(*cp); - if (isdigit(c) && c < '8') { - num64 = (c - '0') + (num64 * radix); - } else { - break; - } - cp++; - } - } - } - - if (negative) { - return 0 - num64; - } - return num64; -} - -#endif /* BLD_FEATURE_INT64 */ -/******************************************************************************/ -/* - * Convert the string buffer to an Integer. - */ - -int ejsParseInteger(const char *str) -{ - const char *cp; - int num; - int radix, c, negative; - - mprAssert(str); - - cp = str; - num = 0; - negative = 0; - - if (*cp == '-') { - cp++; - negative = 1; - } else if (*cp == '+') { - cp++; - } - - /* - * Parse a number. Observe hex and octal prefixes (0x, 0) - */ - if (*cp != '0') { - /* - * Normal numbers (Radix 10) - */ - while (isdigit((int) *cp)) { - num = (*cp - '0') + (num * 10); - cp++; - } - } else { - cp++; - if (tolower(*cp) == 'x') { - cp++; - radix = 16; - while (*cp) { - c = tolower(*cp); - if (isdigit(c)) { - num = (c - '0') + (num * radix); - } else if (c >= 'a' && c <= 'f') { - num = (c - 'a' + 10) + (num * radix); - } else { - break; - } - cp++; - } - - } else{ - radix = 8; - while (*cp) { - c = tolower(*cp); - if (isdigit(c) && c < '8') { - num = (c - '0') + (num * radix); - } else { - break; - } - cp++; - } - } - } - - if (negative) { - return 0 - num; - } - return num; -} - -/******************************************************************************/ -#if BLD_FEATURE_FLOATING_POINT -/* - * Convert the string buffer to an Floating. - */ - -double ejsParseFloat(const char *str) -{ - return atof(str); -} - -/******************************************************************************/ - -int ejsIsNan(double f) -{ -#if WIN - return _isnan(f); -#elif VXWORKS - /* FUTURE */ - return (0); -#else - return (f == FP_NAN); -#endif -} -/******************************************************************************/ - -int ejsIsInfinite(double f) -{ -#if WIN - return !_finite(f); -#elif VXWORKS - /* FUTURE */ - return (0); -#else - return (f == FP_INFINITE); -#endif -} - -#endif /* BLD_FEATURE_FLOATING_POINT */ - -/******************************************************************************/ -/* - * Single point of control for all assignment to properties. - * - * Copy an objects core value (only). This preserves the destination object's - * name. This implements copy by reference for objects and copy by value for - * strings and other types. Caller must free dest prior to calling. - */ - -static EjsVar *copyVar(EJS_LOC_DEC(ep, loc), EjsVar *dest, const EjsVar *src, - EjsCopyDepth copyDepth) -{ - Ejs *ejsContext; - EjsObj *srcObj; - EjsProperty *destp; - const char **srcArgs; - char *str; - int i; - - mprAssert(dest); - mprAssert(src); - - if (dest == src) { - return dest; - } - - if (dest->type != EJS_TYPE_UNDEFINED) { - ejsClearVar(ep, dest); - } - - dest->allocatedData = 0; - - switch (src->type) { - default: - case EJS_TYPE_UNDEFINED: - case EJS_TYPE_NULL: - break; - - case EJS_TYPE_BOOL: - dest->boolean = src->boolean; - break; - - case EJS_TYPE_PTR: - dest->ptr = src->ptr; - if (dest->ptr.destructor) { - dest->allocatedData = 1; - } - break; - - case EJS_TYPE_STRING_CMETHOD: - dest->cMethodWithStrings = src->cMethodWithStrings; - break; - - case EJS_TYPE_CMETHOD: - dest->cMethod = src->cMethod; - break; - -#if BLD_FEATURE_FLOATING_POINT - case EJS_TYPE_FLOAT: - dest->floating = src->floating; - break; -#endif - - case EJS_TYPE_INT: - dest->integer = src->integer; - break; - -#if BLD_FEATURE_INT64 - case EJS_TYPE_INT64: - dest->integer64 = src->integer64; - break; -#endif - - case EJS_TYPE_OBJECT: - if (copyDepth == EJS_SHALLOW_COPY) { - - /* - * If doing a shallow copy and the src object is from the same - * interpreter, or we are copying from the master interpreter, or - * we are using a shared slab, then we can do a shallow copy. - * Otherwise, we must do a deep copy. - */ - srcObj = src->objectState; - if (srcObj->ejs == ep || srcObj->ejs == ep->service->master || - (ep->flags & EJS_FLAGS_SHARED_SLAB)) { - dest->objectState = src->objectState; - dest->allocatedData = 1; - break; - } - } - - /* - * Doing a deep or recursive deep. Can get here if doing a shallow - * copy and the object is from another non-master interpeter and not - * using a shared slab. - * - * We must make sure the data is allocated using the right memory - * context. It must be the same as the destination parent object. - * Otherwise, when we free the property memory, the parent may - * have a dangling pointer. - */ - if (dest->isProperty) { - destp = ejsGetPropertyPtr(dest); - if (destp->parentObj == 0) { - ejsContext = ep; - - } else { - mprAssert(destp->parentObj); - ejsContext = destp->parentObj->ejs; - mprAssert(ejsContext); - } - - } else { - ejsContext = ep; - } - - dest->objectState = createObj(EJS_LOC_PASS(ejsContext, loc)); - if (dest->objectState == 0) { - /* Memory Error */ - return 0; - } - - dest->objectState->baseClass = src->objectState->baseClass; - dest->objectState->methods = src->objectState->methods; - dest->objectState->noConstructor = src->objectState->noConstructor; - dest->objectState->objName = - mprStrdup(ejsContext, src->objectState->objName); - - if (dest->objectState->objName == 0) { - return 0; - } - - if (ejsCopyProperties(ep, dest, src, copyDepth) == 0) { - return 0; - } - dest->allocatedData = 1; - break; - - case EJS_TYPE_METHOD: - dest->method.args = mprCreateItemArray(ep, EJS_INC_ARGS, - EJS_MAX_ARGS); - if (dest->method.args == 0) { - return 0; - } - dest->allocatedData = 1; - if (src->method.args) { - srcArgs = (const char**) src->method.args->items; - for (i = 0; i < src->method.args->length; i++) { - str = mprStrdupInternal(EJS_LOC_PASS(dest->method.args, - loc), srcArgs[i]); - if (str == 0) { - mprFree(dest->method.args); - dest->method.args = 0; - return 0; - } - if (mprAddItem(dest->method.args, str) < 0) { - mprFree(dest->method.args); - dest->method.args = 0; - return 0; - } - } - } - dest->method.body = mprStrdup(dest->method.args, src->method.body); - if (dest->method.body == 0) { - mprFree(dest->method.args); - dest->method.args = 0; - return 0; - } - dest->callsSuper = src->callsSuper; - break; - - case EJS_TYPE_STRING: - dest->length = src->length; - if (src->string) { - /* Shallow, deep or recursive deep */ - dest->length = dupString(MPR_LOC_PASS(ep, loc), &dest->ustring, - src->ustring, src->length); - if (dest->length < 0) { - return 0; - } - dest->allocatedData = 1; - - } else { - dest->string = src->string; - dest->allocatedData = 0; - } - break; - } - - dest->type = src->type; - dest->flags = src->flags; - dest->isArray = src->isArray; - - return dest; -} - -/******************************************************************************/ -/* - * Copy all properies in an object. Must preserve property order - */ - -EjsVar *ejsCopyProperties(Ejs *ep, EjsVar *dest, const EjsVar *src, - EjsCopyDepth copyDepth) -{ - EjsProperty *srcProp, *destProp, *last, *next; - int propertyIndex; - - srcProp = ejsGetFirstProperty(src, EJS_ENUM_ALL); - while (srcProp) { - next = ejsGetNextProperty(srcProp, EJS_ENUM_ALL); - if (srcProp->visited) { - srcProp = next; - continue; - } - - /* - * This finds the last variable in the hash chain - * FUTURE OPT. This is slow. If used double link, we could locate the - * tail more easily. - */ - destProp = hashLookup(dest->objectState, srcProp->name, - &propertyIndex, &last); - mprAssert(destProp == 0); - - destProp = allocProperty(ep, dest, srcProp->name, propertyIndex, last); - if (destProp == 0) { - mprAssert(destProp); - return 0; - } - - /* - * Recursively copy the object. If DEEP_COPY, then we - * will do a shallow copy of the object contents. If - * RECURSIVE_DEEP, then we do a deep copy at all levels. - */ - srcProp->visited = 1; - - if (copyVar(EJS_LOC_ARGS(ep), ejsGetVarPtr(destProp), - ejsGetVarPtr(srcProp), - (copyDepth == EJS_DEEP_COPY) ? EJS_SHALLOW_COPY : copyDepth) - == 0) { - return 0; - } - srcProp->visited = 0; - - srcProp = next; - } - return dest; -} - -/******************************************************************************/ -/********************************** Properties ********************************/ -/******************************************************************************/ -/* - * Create a property in an object and return a pointer to it. If the property - * already exists then just return a pointer to it (no error). - * To test for existance of a property, use GetProperty - */ - -static EjsProperty *hashLookup(EjsObj *obj, const char *property, - int *propertyIndex, EjsProperty **hashTail) -{ - EjsProperty *prop, *last; - int index; - - mprAssert(obj); - mprAssert(property); - - if (obj == 0 || property == 0 || *property == '\0') { - mprAssert(0); - return 0; - } - - /* - * Find the property in the hash chain if it exists - */ - index = hash(property); - prop = obj->propertyHash[index]; - for (last = 0; prop != 0; last = prop, prop = prop->hashNext) { - if (prop->name[0] == property[0] && - strcmp(prop->name, property) == 0) { - break; - } - } - if (propertyIndex) { - *propertyIndex = index; - } - if (hashTail) { - *hashTail = last; - } - - return prop; -} - -/******************************************************************************/ -/* - * Create a property in an object and return a pointer to it. If the property - * already exists then just return a pointer to it (no error). If the property - * does not exist, create an undefined variable. To test for existance of a - * property, use GetProperty. - */ - -EjsProperty *ejsCreateSimpleProperty(Ejs *ep, EjsVar *op, const char *property) -{ - EjsProperty *prop, *last; - int propertyIndex; - - if (op == 0 || op->type != EJS_TYPE_OBJECT || property == 0 || - *property == '\0') { - mprAssert(0); - return 0; - } - - /* - * Find the property in the hash chain if it exists - */ - prop = hashLookup(op->objectState, property, &propertyIndex, &last); - - if (prop == 0) { - /* - * Create a new property - */ - prop = allocProperty(ep, op, property, propertyIndex, last); - if (prop == 0) { - mprAssert(prop == 0); - return 0; - } - } - return prop; -} - -/******************************************************************************/ -/* - * Create a property in an object and return a pointer to it. If the property - * already exists then just return a pointer to it (no error). - * To test for existance of a property, use GetProperty - */ - -EjsProperty *ejsCreateSimpleNonUniqueProperty(Ejs *ep, EjsVar *op, - const char *property) -{ - EjsProperty *prop, *last; - int propertyIndex; - - if (op == 0 || op->type != EJS_TYPE_OBJECT || property == 0 || - *property == '\0') { - mprAssert(0); - return 0; - } - - /* - * Find end of chain - */ - propertyIndex = hash(property); - prop = op->objectState->propertyHash[propertyIndex]; - for (last = 0; prop != 0; last = prop, prop = prop->hashNext) { - ; - } - - return allocProperty(ep, op, property, propertyIndex, last); -} - -/******************************************************************************/ -/* - * Find a property in an object and return a pointer to it. - * This does NOT traverse base classes. - */ - -EjsProperty *ejsGetSimpleProperty(Ejs *ep, EjsVar *op, const char *property) -{ - mprAssert(op); - mprAssert(op->type == EJS_TYPE_OBJECT); - mprAssert(property && *property); - - /* - * This is an internal API. It has very little checking. - */ - return hashLookup(op->objectState, property, 0, 0); -} - -/******************************************************************************/ - -/* - * NOTE: There is no ejsSetSimpleProperty as all the ejsSetProperty routines - * operate only on the instance and don't follow base classes. ie. there is - * no simple version required. However, there is a ejsSetBaseProperty routine - * that will follow base classes and is used to set static properties in base - * classes - */ - -/******************************************************************************/ -/******************************* Property Access ******************************/ -/******************************************************************************/ -/* - * The property get routines follow base classes and utilize the propery - * method access routines. The property set routines do not follow base - * classes. The property ejsSetBase... routines do follow base classes. - */ - -/* - * Find a property in an object and return a pointer to it. - * This follows base classes. - */ - -EjsProperty *ejsGetProperty(Ejs *ep, EjsVar *op, const char *property) -{ - EjsVar *vp, *newOp; - int maxBaseClasses = 50; - - do { - if (op->type != EJS_TYPE_OBJECT) { - mprAssert(op->type == EJS_TYPE_OBJECT); - return 0; - } - mprAssert(op->objectState); - - vp = ejsGetPropertyMethod(ep, op, property); - if (vp != 0) { - /* - * Found - */ - break; - } - - newOp = op->objectState->baseClass; - if (newOp == 0) { - if (op->objectState != ep->objectClass->objectState) { - newOp = ep->objectClass; - } - } - op = newOp; - - /* - * A little bit of sanity checking - */ - if (--maxBaseClasses <= 0) { - mprAssert(maxBaseClasses > 0); - break; - } - - } while (op); - - return ejsGetPropertyPtr(vp); -} - -/******************************************************************************/ -/* - * Get the property's variable. Optionally create if it does not exist. - */ - -EjsVar *ejsGetPropertyAsVar(Ejs *ep, EjsVar *vp, const char *property) -{ - return ejsGetVarPtr(ejsGetProperty(ep, vp, property)); -} - -/******************************************************************************/ -/* - * Get the property's value as a binary string. - */ - -const uchar *ejsGetPropertyAsBinaryString(Ejs *ep, EjsVar *obj, - const char *property, int *length) -{ - EjsVar *vp; - - vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); - if (vp == 0 || ejsVarIsUndefined(vp)) { - return 0; - } - - if (vp->type == EJS_TYPE_STRING) { - if (length) { - *length = vp->length; - } - return vp->ustring; - } - return 0; -} - -/******************************************************************************/ -/* - * Get the property's value as a string. - */ - -const char *ejsGetPropertyAsString(Ejs *ep, EjsVar *obj, const char *property) -{ - EjsVar *vp; - - vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); - if (vp == 0 || ejsVarIsUndefined(vp)) { - return 0; - } - - if (vp->type == EJS_TYPE_STRING) { - return vp->string; - } - return 0; -} - -/******************************************************************************/ -/* - * Get the property's value as a number. - */ - -BLD_FEATURE_NUM_TYPE ejsGetPropertyAsNumber(Ejs *ep, EjsVar *obj, - const char *property) -{ - EjsVar *vp; - - vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); - if (vp == 0 || ejsVarIsUndefined(vp)) { - return 0; - } - - return ejsVarToNumber(vp); -} - -/******************************************************************************/ -/* - * Get the property's value as a integer. - */ - -int ejsGetPropertyAsInteger(Ejs *ep, EjsVar *obj, const char *property) -{ - EjsVar *vp; - - vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); - if (vp == 0 || ejsVarIsUndefined(vp)) { - return 0; - } - - return ejsVarToInteger(vp); -} - -/******************************************************************************/ -/* - * Get the property's value as a boolean. - */ - -bool ejsGetPropertyAsBoolean(Ejs *ep, EjsVar *obj, const char *property) -{ - EjsVar *vp; - - vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); - if (vp == 0 || ejsVarIsUndefined(vp)) { - return 0; - } - - return ejsVarToBoolean(vp); -} - -/******************************************************************************/ -/* - * Get the property's value as a pointer. - */ - -void *ejsGetPropertyAsPtr(Ejs *ep, EjsVar *obj, const char *property) -{ - EjsVar *vp; - - vp = ejsGetVarPtr(ejsGetProperty(ep, obj, property)); - if (vp == 0 || ejsVarIsUndefined(vp)) { - return 0; - } - if (vp->type == EJS_TYPE_PTR) { - return vp->ptr.userPtr; - } - return 0; -} - -/******************************************************************************/ -/* - * Create a property in the object. This will override any base class - * properties. - * - * MOB -- need to spell out the difference between ejsSetProperty and - * ejsCreateProperty. - */ - -EjsProperty *ejsCreateProperty(Ejs *ep, EjsVar *obj, const char *property) -{ - EjsVar *vp; - - vp = ejsCreatePropertyMethod(ep, obj, property); - return ejsGetPropertyPtr(vp); -} - -/******************************************************************************/ -/* - * Set a property's variable value. Create the property if it does not exist. - * This routine DOES follow base classes. - */ - -EjsProperty *ejsSetBaseProperty(Ejs *ep, EjsVar *op, const char *property, - const EjsVar *value) -{ - EjsVar *vp, *newOp; - int maxBaseClasses = 50; - - do { - if (op->type != EJS_TYPE_OBJECT) { - mprAssert(op->type == EJS_TYPE_OBJECT); - return 0; - } - mprAssert(op->objectState); - - vp = ejsGetPropertyMethod(ep, op, property); - if (vp != 0) { - /* - * Found - */ - vp = ejsSetPropertyMethod(ep, op, property, value); - break; - } - - newOp = op->objectState->baseClass; - if (newOp == 0) { - if (op->objectState != ep->objectClass->objectState) { - newOp = ep->objectClass; - } - } - op = newOp; - - /* - * A little bit of sanity checking - */ - if (--maxBaseClasses <= 0) { - mprAssert(maxBaseClasses > 0); - break; - } - - } while (op); - - return ejsGetPropertyPtr(vp); -} - -/******************************************************************************/ -/* - * Set a property's variable value. Create the property if it does not exist. - * This does NOT follow base classes. Okay when updating instance properties, - * but not for class (static) properties. This does a shallow copy which - * will copy references. - */ - -EjsProperty *ejsSetProperty(Ejs *ep, EjsVar *obj, const char *property, - const EjsVar *value) -{ - EjsVar *vp; - - vp = ejsSetPropertyMethod(ep, obj, property, value); - - return ejsGetPropertyPtr(vp); -} - -/******************************************************************************/ -/* - * Set a property's variable value by assigning the given value. The caller - * must NOT free value as it is assigned directly into the property's value. - */ - -EjsProperty *ejsSetPropertyAndFree(Ejs *ep, EjsVar *obj, - const char *property, EjsVar *value) -{ - EjsVar *vp; - - vp = ejsSetPropertyMethod(ep, obj, property, value); - - ejsFree(ep, value, EJS_SLAB_VAR); - - return ejsGetPropertyPtr(vp); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToCMethod(Ejs *ep, EjsVar *vp, const char *prop, - EjsCMethod fn, void *userData, int flags) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_CMETHOD); - v.cMethod.fn = fn; - v.cMethod.userData = userData; - v.flags = flags; - - return ejsSetProperty(ep, vp, prop, &v); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToBoolean(Ejs *ep, EjsVar *vp, const char *prop, - int value) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_BOOL); - v.boolean = value; - - return ejsSetProperty(ep, vp, prop, &v); -} - -/******************************************************************************/ -#if BLD_FEATURE_FLOATING_POINT - -EjsProperty *ejsSetPropertyToFloat(Ejs *ep, EjsVar *vp, const char *prop, - double value) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_FLOAT); - v.floating = value; - - return ejsSetProperty(ep, vp, prop, &v); -} - -#endif -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToInteger(Ejs *ep, EjsVar *vp, const char *prop, - int value) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_INT); - v.integer = value; - - return ejsSetProperty(ep, vp, prop, &v); -} - -/******************************************************************************/ -#if BLD_FEATURE_INT64 - -EjsProperty *ejsSetPropertyToInteger64(Ejs *ep, EjsVar *vp, const char *prop, - int64 value) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_INT64); - v.integer64 = value; - - return ejsSetProperty(ep, vp, prop, &v); -} - -#endif -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToNull(Ejs *ep, EjsVar *vp, const char *prop) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_NULL); - - return ejsSetProperty(ep, vp, prop, &v); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToMethod(Ejs *ep, EjsVar *vp, const char *prop, - const char *body, MprArray *args, int flags) -{ - return ejsSetPropertyAndFree(ep, vp, prop, - ejsCreateMethodVar(ep, body, args, flags)); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToNumber(Ejs *ep, EjsVar *vp, const char *prop, - EjsNum value) -{ - return ejsSetPropertyAndFree(ep, vp, prop, ejsCreateNumberVar(ep, value)); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToStringCMethod(Ejs *ep, EjsVar *vp, - const char *prop, EjsStringCMethod fn, void *userData, int flags) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_STRING_CMETHOD); - v.cMethodWithStrings.fn = fn; - v.cMethodWithStrings.userData = userData; - v.flags = flags; - - return ejsSetProperty(ep, vp, prop, &v); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToString(Ejs *ep, EjsVar *vp, const char *prop, - const char *value) -{ - EjsProperty *pp; - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_STRING); - - /* FUTURE OPT */ - v.string = mprStrdupInternal(EJS_LOC_ARGS(ep), value); - if (v.string == 0) { - return 0; - } - v.length = strlen(v.string); - v.allocatedData = 1; - - pp = ejsSetProperty(ep, vp, prop, &v); - - mprFree(v.string); - - return pp; -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToBinaryString(Ejs *ep, EjsVar *vp, - const char *prop, const uchar *value, int len) -{ - EjsProperty *pp; - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_STRING); - - /* FUTURE OPT */ - v.length = dupString(MPR_LOC_ARGS(ep), &v.ustring, value, len); - if (v.length < 0) { - return 0; - } - v.allocatedData = 1; - - pp = ejsSetProperty(ep, vp, prop, &v); - - mprFree(v.ustring); - - return pp; -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToUndefined(Ejs *ep, EjsVar *vp, const char *prop) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_UNDEFINED); - - return ejsSetProperty(ep, vp, prop, &v); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToPtr(Ejs *ep, EjsVar *vp, const char *prop, - void *ptr, EjsDestructor destructor) -{ - EjsVar v; - - ejsInitVar(&v, EJS_TYPE_PTR); - v.ptr.userPtr = ptr; - v.ptr.destructor = destructor; - v.allocatedData = 1; - - return ejsSetProperty(ep, vp, prop, &v); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToNewObj(Ejs *ep, EjsVar *vp, const char *prop, - const char *className, MprArray *args) -{ - return ejsSetPropertyAndFree(ep, vp, prop, - ejsCreateObjUsingArgv(ep, 0, className, args)); -} - -/******************************************************************************/ - -EjsProperty *ejsSetPropertyToObj(Ejs *ep, EjsVar *op, const char *prop) -{ - return ejsSetPropertyAndFree(ep, op, prop, ejsCreateObjVar(ep)); -} - -/******************************************************************************/ -/* - * Convenience routines - */ - -EjsVar *ejsSetPropertyToObjAsVar(Ejs *ep, EjsVar *op, const char *prop) -{ - return ejsGetVarPtr(ejsSetPropertyToObj(ep, op, prop)); -} - -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ -/******************************************************************************/ -/* - * Create a script method - */ - -EjsProperty *ejsDefineMethod(Ejs *ep, EjsVar *vp, const char *prop, - const char *body, MprArray *args) -{ - if (vp == 0) { - vp = ejsGetGlobalObj(ep); - } - return ejsSetPropertyToMethod(ep, vp, prop, body, args, 0); -} - -/******************************************************************************/ -/* - * Create a C language method - */ - -EjsProperty *ejsDefineCMethod(Ejs *ep, EjsVar *vp, const char *prop, - EjsCMethod fn, int flags) -{ - if (vp == 0) { - vp = ejsGetGlobalObj(ep); - } - return ejsSetPropertyToCMethod(ep, vp, prop, fn, 0, flags); -} - -/******************************************************************************/ -/* - * Define accessors - */ - -EjsProperty *ejsDefineAccessors(Ejs *ep, EjsVar *vp, const char *prop, - const char *getBody, const char *setBody) -{ - EjsProperty *pp; - MprArray *args; - char *propName; - - if (vp == 0) { - vp = ejsGetGlobalObj(ep); - } - - if (ejsSetPropertyToMethod(ep, vp, prop, getBody, 0, EJS_GET_ACCESSOR) < 0){ - ejsMemoryError(ep); - return 0; - } - - /* MOB -- OPT to use SLAB */ - /* MOB -- need to encapsulate this logic */ - - if (mprAllocStrcat(MPR_LOC_ARGS(ep), &propName, EJS_MAX_ID+5, 0, - "-set-", prop, NULL) < 0) { - ejsMemoryError(ep); - return 0; - } - - args = mprCreateItemArray(ep, EJS_INC_ARGS, EJS_MAX_ARGS); - mprAddItem(args, mprStrdup(args, "value")); - - pp = ejsSetPropertyToMethod(ep, vp, propName, setBody, args, - EJS_SET_ACCESSOR); - mprFree(propName); - - if (pp == 0) { - ejsMemoryError(ep); - return 0; - } - - return pp; -} - -/******************************************************************************/ -/* - * Define C accessors - */ - -EjsProperty *ejsDefineCAccessors(Ejs *ep, EjsVar *vp, const char *prop, - EjsCMethod getFn, EjsCMethod setFn, int flags) -{ - EjsProperty *pp; - char *propName; - - if (vp == 0) { - vp = ejsGetGlobalObj(ep); - } - pp = ejsSetPropertyToCMethod(ep, vp, prop, getFn, 0, - flags | EJS_GET_ACCESSOR); - if (pp == 0) { - ejsMemoryError(ep); - return 0; - } - - /* MOB -- OPT to use SLAB */ - if (mprAllocStrcat(MPR_LOC_ARGS(ep), &propName, EJS_MAX_ID + 5, 0, - "-set-", prop, NULL) < 0) { - ejsMemoryError(ep); - return 0; - } - pp = ejsSetPropertyToCMethod(ep, vp, propName, setFn, 0, - flags | EJS_SET_ACCESSOR); - mprFree(propName); - - if (pp == 0) { - ejsMemoryError(ep); - return 0; - } - return pp; -} - -/******************************************************************************/ -/* - * Create a C language method with string arguments - */ - -EjsProperty *ejsDefineStringCMethod(Ejs *ep, EjsVar *vp, const char *prop, - EjsStringCMethod fn, int flags) -{ - if (vp == 0) { - vp = ejsGetGlobalObj(ep); - } - return ejsSetPropertyToStringCMethod(ep, vp, prop, fn, 0, flags); -} - -/******************************************************************************/ - -void ejsSetCMethodUserData(EjsVar *obj, void *userData) -{ - /* - * This is a little dirty. We rely on the userData being in the same - * place in the var structure. - */ - obj->cMethod.userData = userData; -} - -/******************************************************************************/ - -void ejsSetVarFlags(EjsVar *obj, int flags) -{ - obj->flags = flags; -} - -/******************************************************************************/ - -void *ejsGetCMethodUserData(EjsVar *obj) -{ - return obj->cMethod.userData; -} - -/******************************************************************************/ - -int ejsGetVarFlags(EjsVar *obj) -{ - return obj->flags; -} - -/******************************************************************************/ - -void ejsSetObjDestructor(Ejs *ep, EjsVar *obj, EjsDestructor destructor) -{ - obj->objectState->destructor = destructor; -} - -/******************************************************************************/ - -void ejsClearObjDestructor(Ejs *ep, EjsVar *obj) -{ - obj->objectState->destructor = 0; -} - -/******************************************************************************/ -/* - * Create a new property - */ - -static EjsProperty *allocProperty(Ejs *ep, EjsVar *op, const char *property, - int propertyIndex, EjsProperty *last) -{ - EjsProperty *prop; - EjsObj *obj; - - obj = op->objectState; - - /* - * Allocate the property using the memory context of the owning object - */ - prop = ejsAllocProperty(EJS_LOC_ARGS(obj->ejs)); - if (prop == 0) { - return 0; - } - if (mprStrcpy(prop->name, sizeof(prop->name), property) < 0) { - ejsError(ep, EJS_REFERENCE_ERROR, - "Property name %s is too long. Max is %d letters.", - prop->name, EJS_MAX_ID); - return 0; - } - - ejsSetVarName(ep, ejsGetVarPtr(prop), &prop->name[0]); - - /* - * Do hash linkage - */ - if (last) { - last->hashNext = prop; - } else { - obj->propertyHash[propertyIndex] = prop; - } - -#if BLD_DEBUG - prop->link.propertyName = prop->name; - prop->link.property = prop; - prop->link.head = &obj->link; -#endif - - /* - * Inserting before the dummy head will append to the end - */ - linkPropertyBefore(obj, &obj->link, &prop->link); - - obj->numProperties++; - prop->parentObj = obj; - mprAssert(obj->ejs); - - return prop; -} - -/******************************************************************************/ -/* - * Delete a property from this object - */ - -int ejsDeleteProperty(Ejs *ep, EjsVar *vp, const char *property) -{ - EjsProperty *prop, *last; - EjsObj *obj; - int propertyIndex; - - mprAssert(vp); - mprAssert(property && *property); - mprAssert(vp->type == EJS_TYPE_OBJECT); - - if (vp->type != EJS_TYPE_OBJECT) { - mprAssert(vp->type == EJS_TYPE_OBJECT); - return MPR_ERR_BAD_ARGS; - } - - prop = hashLookup(vp->objectState, property, &propertyIndex, &last); - if (prop == (EjsProperty*) 0) { - return MPR_ERR_NOT_FOUND; - } - obj = vp->objectState; - -#if FUTURE - if (prop->readonly) { - mprAssert(! prop->readonly); - return MPR_ERR_READ_ONLY; - } -#endif - - /* - * If doing enumerations, then the object will mark preventDelete to - * prevent any properties being deleted and thus disturbing the - * traversal. - */ - if (obj->preventDeleteProp) { - obj->delayedDeleteProp = 1; - prop->delayedDelete = 1; - return 0; - } - - /* - * Remove from hash - */ - if (last) { - last->hashNext = prop->hashNext; - } else { - obj->propertyHash[propertyIndex] = prop->hashNext; - } - - unlinkProperty(obj, &prop->link); - obj->numProperties--; - - /* - * Free any property data and return to the slab - */ - if (prop->var.type != EJS_TYPE_OBJECT) { - ejsClearVar(ep, ejsGetVarPtr(prop)); - } - ejsFree(ep, prop, EJS_SLAB_PROPERTY); - - return 0; -} - -/******************************************************************************/ -/* - * Remove a property's value from this object. The property is set to - * undefined. - */ - -EjsVar *ejsClearProperty(Ejs *ep, EjsVar *vp, const char *property) -{ - EjsProperty *prop; - - mprAssert(vp); - mprAssert(property && *property); - mprAssert(vp->type == EJS_TYPE_OBJECT); - - if (vp->type != EJS_TYPE_OBJECT) { - mprAssert(vp->type == EJS_TYPE_OBJECT); - return 0; - } - - prop = hashLookup(vp->objectState, property, 0, 0); - if (prop == (EjsProperty*) 0) { - return 0; - } -#if FUTURE - if (prop->readonly) { - mprAssert(! prop->readonly); - return 0; - } -#endif - - ejsClearVar(ep, &prop->var); - return &prop->var; -} - -/******************************************************************************/ -/* - * Unlink a property from the ordered list of properties - */ - -static void unlinkProperty(EjsObj *obj, EjsPropLink *propLink) -{ - propLink->prev->next = propLink->next; - propLink->next->prev = propLink->prev; -} - -/******************************************************************************/ -#if UNUSED && KEEP -/* - * Insert a link after a specified link. - */ - -static void linkPropertyAfter(EjsObj *obj, EjsPropLink *at, - EjsPropLink *propLink) -{ - propLink->next = at->next; - propLink->prev = at; - - at->next->prev = propLink; - at->next = propLink; -} - -#endif -/******************************************************************************/ -/* - * Insert a link before a specified link. - */ - -static void linkPropertyBefore(EjsObj *obj, EjsPropLink *at, - EjsPropLink *propLink) -{ - propLink->prev = at->prev; - propLink->next = at; - - at->prev->next = propLink; - at->prev = propLink; -} - -/******************************************************************************/ -/* - * This routine will sort properties in an object. If propertyName is not - * null, then the properties in op must be objects with a property of the - * name propertyName. If propertyName is null, then the properties of op - * are directly sorted. If order is 1, they are sorted in ascending order. - * If -1, they are sorted in descending order. - * - * NOTE: arrays keep their original index values. - */ - -void ejsSortProperties(Ejs *ep, EjsVar *op, EjsSortFn fn, - const char *propertyName, int order) -{ - EjsProperty *p1, *p2, *tmp; - EjsPropLink *l1, *l2, *oldL1Spot; - EjsObj *obj; - - obj = op->objectState; - - p1 = ejsGetFirstProperty(op, 0); - while (p1) { - if (p1->dontEnumerate) { - p1 = ejsGetNextProperty(p1, 0); - continue; - } - - p2 = ejsGetFirstProperty(op, 0); - while (p2 && p2 != p1) { - - if (p2->dontEnumerate) { - p2 = ejsGetNextProperty(p2, 0); - continue; - } - - if (fn == 0) { - if (propertyName) { - fn = sortByProperty; - } else { - fn = sortAllProperties; - } - } - - if (fn(ep, p1, p2, propertyName, order) < 0) { - - l1 = &p1->link; - l2 = &p2->link; - - /* - * Swap the properties without disturbing the hash chains. - * l1 is always after l2 in the list. Unlink l1 and remember - * the one after l1. - */ - oldL1Spot = l1->next; - unlinkProperty(obj, l1); - - /* - * Manually reinsert l1 by replacing l2 with l1. l2 is out of - * the chain. - */ - l2->prev->next = l1; - l2->next->prev = l1; - l1->prev = l2->prev; - l1->next = l2->next; - - /* - * Reinsert l2 before the spot where l1 was. - */ - linkPropertyBefore(obj, oldL1Spot, l2); - - /* - * Swap the pointers so we continue to traverse correctly - */ - tmp = p1; - p1 = p2; - p2 = tmp; - } - p2 = ejsGetNextProperty(p2, 0); - } - p1 = ejsGetNextProperty(p1, 0); - } -} - -/******************************************************************************/ -/* - * Sort properties. Strings are sorted in ascending ASCII collating sequence - * Numbers are sorted in increasing numerical order. - */ -static int sortAllProperties(Ejs *ep, EjsProperty *p1, EjsProperty *p2, - const char *propertyName, int order) -{ - EjsVar *v1, *v2; - char *buf1, *buf2; - int rc, buf1Alloc; - - v1 = ejsGetVarPtr(p1); - v2 = ejsGetVarPtr(p2); - - if (v1->type == v2->type) { - /* MOB -- should support Numbers */ - if (v1->type == EJS_TYPE_INT) { - if (v1->integer < v2->integer) { - return - order; - - } else if (v1->integer == v2->integer) { - return 0; - } - return order; - -#if BLD_FEATURE_FLOATING_POINT - } else if (v1->type == EJS_TYPE_FLOAT) { - if (v1->floating < v2->floating) { - return - order; - - } else if (v1->floating == v2->floating) { - return 0; - } - return order; - -#endif - } else if (v1->type == EJS_TYPE_STRING) { - /* MOB -- need binary support ? */ - return strcmp(v1->string, v2->string) * order; - - } else { - - buf1 = ejsVarToStringEx(ep, v1, &buf1Alloc); - buf2 = ejsVarToString(ep, v2); - - rc = strcmp(buf1, buf2); - - if (buf1Alloc) { - mprFree(buf1); - } - - return rc * order; - } - - } else { - /* Type mismatch in array */ - return 0; - } - return 0; -} - -/******************************************************************************/ -/* - * Sort an object by a given property. - */ -static int sortByProperty(Ejs *ep, EjsProperty *p1, EjsProperty *p2, - const char *propertyName, int order) -{ - EjsVar *o1, *o2, *v1, *v2; - char *buf1, *buf2; - int rc, buf1Alloc; - - o1 = ejsGetVarPtr(p1); - o2 = ejsGetVarPtr(p2); - - if (!ejsVarIsObject(o1) || !ejsVarIsObject(o2)) { - mprAssert(ejsVarIsObject(o1)); - mprAssert(ejsVarIsObject(o2)); - return 0; - } - - v1 = ejsGetPropertyAsVar(ep, o1, propertyName); - v2 = ejsGetPropertyAsVar(ep, o2, propertyName); - - if (v1 == 0 || v2 == 0) { - /* Property name not found */ - return 0; - } - - if (v1->type != v2->type) { - mprAssert(v1->type == v2->type); - return 0; - } - - if (v1->type == v2->type) { - /* MOB -- should support Numbers */ - if (v1->type == EJS_TYPE_INT) { - if (v1->integer < v2->integer) { - return -order; - - } else if (v1->integer == v2->integer) { - return 0; - } - return order; - -#if BLD_FEATURE_FLOATING_POINT - } else if (v1->type == EJS_TYPE_FLOAT) { - if (v1->floating < v2->floating) { - return -order; - - } else if (v1->floating == v2->floating) { - return 0; - } - return order; - -#endif - } else if (v1->type == EJS_TYPE_STRING) { - /* MOB -- need binary support ? */ - return strcmp(v1->string, v2->string) * order; - - } else { - buf1 = ejsVarToStringEx(ep, v1, &buf1Alloc); - - buf2 = ejsVarToString(ep, v2); - - rc = strcmp(buf1, buf2); - - if (buf1Alloc) { - mprFree(buf1); - } - - return rc * order; - } - - } else { - /* Type mismatch in array */ - return 0; - } - return 0; -} - -/******************************************************************************/ -/* - * Set a property's name - */ - -void ejsSetPropertyName(EjsProperty *pp, const char *property) -{ - mprStrcpy(pp->name, sizeof(pp->name), property); -} - -/******************************************************************************/ - -int ejsMakePropertyEnumerable(EjsProperty *prop, int enumerate) -{ - int oldValue; - - oldValue = prop->dontEnumerate; - prop->dontEnumerate = !enumerate; - return oldValue; -} - -/******************************************************************************/ - -void ejsMakePropertyPrivate(EjsProperty *prop, int isPrivate) -{ - prop->isPrivate = isPrivate; -} - -/******************************************************************************/ -/* - * Make a variable read only. Can still be deleted. - */ - -void ejsMakePropertyReadOnly(EjsProperty *prop, int readonly) -{ - prop->readonly = readonly; -} - -/******************************************************************************/ - -int ejsMakeObjPermanent(EjsVar *vp, int permanent) -{ - int oldValue; - - if (vp && vp->type == EJS_TYPE_OBJECT) { - oldValue = vp->objectState->permanent; - vp->objectState->permanent = permanent; - } else { - oldValue = 0; - } - return oldValue; -} - -/******************************************************************************/ - -int ejsMakeObjLive(EjsVar *vp, bool alive) -{ - int oldValue; - - oldValue = 0; - if (vp && vp->type == EJS_TYPE_OBJECT) { - oldValue = vp->objectState->alive; - vp->objectState->alive = alive; - } else { - oldValue = 0; - } - return oldValue; -} - -/******************************************************************************/ - -void ejsMakeClassNoConstructor(EjsVar *vp) -{ - mprAssert(vp->type == EJS_TYPE_OBJECT); - - if (vp->type == EJS_TYPE_OBJECT) { - vp->objectState->noConstructor = 1; - } -} - -/******************************************************************************/ -/* - * Get the count of properties. - */ - -int ejsGetPropertyCount(EjsVar *vp) -{ - EjsProperty *pp; - EjsPropLink *lp, *head; - int count; - - mprAssert(vp); - - if (vp->type != EJS_TYPE_OBJECT) { - return 0; - } - - count = 0; - - head = &vp->objectState->link; - for (lp = head->next; lp != head; lp = lp->next) { - pp = ejsGetPropertyFromLink(lp); - if (! pp->dontEnumerate) { - count++; - } - } - return count; -} - -/******************************************************************************/ -/* - * Get the first property in an object. Used for walking all properties in an - * object. This will only enumerate properties in this class and not in base - * classes. - */ - -EjsProperty *ejsGetFirstProperty(const EjsVar *op, int flags) -{ - EjsProperty *pp; - EjsObj *obj; - EjsPropLink *head, *lp; - - mprAssert(op); - mprAssert(op->type == EJS_TYPE_OBJECT); - - if (op->type != EJS_TYPE_OBJECT) { - mprAssert(op->type == EJS_TYPE_OBJECT); - return 0; - } - pp = 0; - - do { - obj = op->objectState; - - head = &obj->link; - lp = head->next; - - while (lp != head) { - pp = ejsGetPropertyFromLink(lp); - if (! pp->dontEnumerate || (flags & EJS_ENUM_HIDDEN)) { - break; - } - lp = lp->next; - } - if (lp != head || op->type != EJS_TYPE_OBJECT || - !(flags & EJS_ENUM_CLASSES)) { - break; - } - - op = obj->baseClass; - - } while (lp == 0 && op); - - return pp; -} - -/******************************************************************************/ -/* - * Get the next property in sequence. This will only enumerate properties in - * this class and not in base classes. - */ - -EjsProperty *ejsGetNextProperty(EjsProperty *last, int flags) -{ - EjsProperty *pp; - EjsObj *obj; - EjsPropLink *lp, *head; - - obj = last->parentObj; - - lp = last->link.next; - head = &obj->link; - pp = 0; - - while (obj) { - while (lp != head) { - pp = ejsGetPropertyFromLink(lp); - if (! pp->dontEnumerate || (flags & EJS_ENUM_HIDDEN)) { - break; - } - lp = lp->next; - } - if (lp != head || !(flags & EJS_ENUM_CLASSES)) { - break; - } - - /* - * Now iterate over properties in base classes (down the chain) - */ - if (obj->baseClass == 0) { - break; - } - - obj = obj->baseClass->objectState; - if (obj == 0) { - break; - } - } - return pp; -} - -/******************************************************************************/ -/* - * Find a variable given a variable name and return the parent object and - * the variable itself. This routine supports literal variable and property - * names that may be objects or arrays but may NOT have expressions. - * Returns -1 on errors or if the variable is not found. - * FUTURE -- Needs OPT - */ - -EjsVar *ejsFindProperty(Ejs *ep, EjsVar **obj, char **property, EjsVar *global, - EjsVar *local, const char *fullName, int create) -{ - EjsProperty *currentProp; - EjsVar *currentObj; - /* MOB -- WARNING BIG */ - char tokBuf[EJS_MAX_ID], propertyName[EJS_MAX_ID]; - char *token, *next, *cp, *endp; - - mprAssert(fullName && *fullName); - - currentProp = 0; - currentObj = 0; - - if (global == 0) { - global = ep->global; - } - - if (obj) { - *obj = 0; - } - if (property) { - *property = 0; - } - - if (fullName == 0) { - return 0; - } - - next = (char*) fullName; - token = getNextVarToken(&next, tokBuf, sizeof(tokBuf)); - mprStrcpy(propertyName, sizeof(propertyName), token); - - if (local) { - currentProp = ejsGetProperty(ep, local, token); - currentObj = local; - } - if (currentProp == 0) { - currentProp = ejsGetProperty(ep, global, token); - currentObj = global; - } - - token = getNextVarToken(&next, tokBuf, sizeof(tokBuf)); - - while (currentObj != 0 && token != 0 && *token) { - - if (currentProp == 0) { - return 0; - } - currentObj = ¤tProp->var; - currentProp = 0; - - if (*token == '[') { - token = getNextVarToken(&next, tokBuf, sizeof(tokBuf)); - - mprStrcpy(propertyName, sizeof(propertyName), token); - cp = propertyName; - if (*cp == '\"') { - cp++; - if ((endp = strchr(cp, '\"')) != 0) { - *endp = '\0'; - } - } else if (*cp == '\'') { - cp++; - if ((endp = strchr(cp, '\'')) != 0) { - *endp = '\0'; - } - } - - currentProp = ejsGetProperty(ep, currentObj, propertyName); - - token = getNextVarToken(&next, tokBuf, sizeof(tokBuf)); - if (*token != ']') { - return 0; - } - - } else if (*token == '.') { - token = getNextVarToken(&next, tokBuf, sizeof(tokBuf)); - if (!isalpha((int) token[0]) && - token[0] != '_' && token[0] != '$') { - return 0; - } - - mprStrcpy(propertyName, sizeof(propertyName), token); - currentProp = ejsGetProperty(ep, currentObj, token); - - } else { - currentProp = ejsGetProperty(ep, currentObj, token); - } - - if (next == 0 || *next == '\0') { - break; - } - token = getNextVarToken(&next, tokBuf, sizeof(tokBuf)); - } - - if (obj) { - *obj = currentObj; - } - - - if (currentProp == 0 && currentObj >= 0 && create) { - currentProp = ejsCreateSimpleProperty(ep, currentObj, propertyName); - } - - if (property) { - *property = currentProp->name; - } - return ejsGetVarPtr(currentProp); -} - -/******************************************************************************/ -/* - * Get the next token as part of a variable specification. This will return - * a pointer to the next token and will return a pointer to the next token - * (after this one) in "next". The tokBuf holds the parsed token. - */ - -static char *getNextVarToken(char **next, char *tokBuf, int tokBufLen) -{ - char *start, *cp; - int len; - - start = *next; - while (isspace((int) *start) || *start == '\n' || *start == '\r') { - start++; - } - cp = start; - - if (*cp == '.' || *cp == '[' || *cp == ']') { - cp++; - } else { - while (*cp && *cp != '.' && *cp != '[' && *cp != ']' && - !isspace((int) *cp) && *cp != '\n' && *cp != '\r') { - cp++; - } - } - len = mprMemcpy(tokBuf, tokBufLen - 1, start, cp - start); - tokBuf[len] = '\0'; - - *next = cp; - return tokBuf; -} - -/******************************************************************************/ - -EjsVar *ejsGetGlobalClass(Ejs *ep) -{ - return ep->global; -} - -/******************************************************************************/ -/*************************** Property Access Methods **************************/ -/******************************************************************************/ -/* - * Create an undefined property. This routine calls the object method hooks. - */ - -/* MOB -- better suffix than "Method" */ -EjsVar *ejsCreatePropertyMethod(Ejs *ep, EjsVar *op, const char *property) -{ - EjsVar *vp; - - mprAssert(ep); - mprAssert(op); - mprAssert(property && *property); - - if (op == 0) { - return 0; - } - - mprAssert(op->type == EJS_TYPE_OBJECT); - mprAssert(op->objectState); - - if (op->objectState == 0) { - return 0; - } - - if (op->objectState->methods == 0) { - vp = ejsGetVarPtr(ejsCreateSimpleProperty(ep, op, property)); - } else { - vp = (op->objectState->methods->createProperty)(ep, op, property); - } - - if (vp == 0) { - mprAssert(vp); - op->objectState->hasErrors = 1; - return 0; - } - - /* - * FUTURE - find a better way. - */ - if (op->isArray) { - ejsSetArrayLength(ep, op, property, 0, 0); - } - return vp; -} - -/******************************************************************************/ - -int ejsDeletePropertyMethod(Ejs *ep, EjsVar *op, const char *property) -{ - int rc; - - mprAssert(ep); - mprAssert(op); - mprAssert(property && *property); - - if (op == 0) { - return -1; - } - - mprAssert(op->type == EJS_TYPE_OBJECT); - mprAssert(op->objectState); - - if (op->objectState == 0) { - return -1; - } - - if (op->objectState->methods == 0) { - rc = ejsDeleteProperty(ep, op, property); - } else { - rc = (op->objectState->methods->deleteProperty)(ep, op, property); - } - - if (rc < 0) { - op->objectState->hasErrors = 1; - } - - op->objectState->dirty = 1; - - return rc; -} - -/******************************************************************************/ -/* - * Set the value of a property. Create if it does not exist - * If the object has property accessor methods defined, use those. - */ - -EjsVar *ejsSetPropertyMethod(Ejs *ep, EjsVar *op, const char *property, - const EjsVar *value) -{ - EjsVar *vp; - - mprAssert(ep); - mprAssert(op); - mprAssert(property && *property); - mprAssert(value); - - if (op == 0) { - return 0; - } - - mprAssert(op->type == EJS_TYPE_OBJECT); - mprAssert(op->objectState); - - if (op->objectState == 0) { - return 0; - } - - if (op->objectState->methods == 0) { - vp = ejsGetVarPtr(ejsCreateSimpleProperty(ep, op, property)); - if (vp && ejsWriteVar(ep, vp, (EjsVar*) value, EJS_SHALLOW_COPY) < 0) { - mprAssert(0); - op->objectState->hasErrors = 1; - return 0; - } - - } else { - vp = (op->objectState->methods->setProperty)(ep, op, property, value); - } - - if (vp == 0) { - mprAssert(vp); - op->objectState->hasErrors = 1; - return 0; - } - - if (vp->type == EJS_TYPE_OBJECT) { - /* - * We make an object alive (and subject to garbage collection) when - * it is referenced in some other object. If this is undesirable, the - * caller should make the object permanent while calling this routine - * and then afterward clear the alive bit by calling ejsMakeObjLive(). - */ - if (op->objectState != vp->objectState) { - vp->objectState->alive = 1; - } -#if BLD_DEBUG - { - EjsProperty *pp = ejsGetPropertyPtr(vp); - ejsSetVarName(ep, vp, &pp->name[0]); - if (value->propertyName == 0) { - ejsSetVarName(ep, (EjsVar*) value, &pp->name[0]); - } - } -#endif - } - - /* - * Trap assignments to array.length. MOB - find a better way. - */ - if (vp->isArrayLength) { - ejsSetArrayLength(ep, op, 0, 0, value); - } - - op->objectState->dirty = 1; - - return vp; -} - -/******************************************************************************/ - -EjsVar *ejsGetPropertyMethod(Ejs *ep, EjsVar *op, const char *property) -{ - mprAssert(ep); - mprAssert(op); - mprAssert(property && *property); - - if (op == 0) { - return 0; - } - - mprAssert(op->type == EJS_TYPE_OBJECT); - mprAssert(op->objectState); - - if (op->objectState == 0) { - return 0; - } - - if (op->objectState->methods == 0) { - return ejsGetVarPtr(ejsGetSimpleProperty(ep, op, property)); - } else { - return (op->objectState->methods->getProperty)(ep, op, property); - } -} - -/******************************************************************************/ -/*************************** Advisory Locking Support *************************/ -/******************************************************************************/ -#if BLD_FEATURE_MULTITHREAD - -void ejsLockObj(EjsVar *vp) -{ - mprAssert(vp); - mprAssert(vp->type == EJS_TYPE_OBJECT); - mprAssert(vp->objectState); - - if (vp->objectState->mutex == 0) { - vp->objectState->mutex = mprCreateLock(vp->objectState->ejs); - } - mprLock(vp->objectState->mutex); -} - -/******************************************************************************/ - -void ejsUnlockObj(EjsVar *vp) -{ - mprAssert(vp); - mprAssert(vp->type == EJS_TYPE_OBJECT); - mprAssert(vp->objectState); - - if (vp->objectState->mutex) { - mprUnlock(vp->objectState->mutex); - } -} - -#endif -/******************************************************************************/ -/************************** Internal Support Routines *************************/ -/******************************************************************************/ -/* - * Create an object. - */ - -static EjsObj *createObj(EJS_LOC_DEC(ep, loc)) -{ - EjsObj *op; - EjsPropLink *lp; - - op = (EjsObj*) ejsAllocObj(EJS_LOC_PASS(ep, loc)); - if (op == NULL) { - return 0; - } - - /* - * The objectState holds the dummy head for the ordered list of properties - */ - lp = &op->link; - lp->next = lp->prev = lp; - -#if BLD_DEBUG - /* - * This makes it much easier to debug the list - */ - lp->head = lp; - lp->propertyName = "dummyHead"; -#endif - - return op; -} - -/******************************************************************************/ -/* - * Destroy an object. Called by the garbage collector if there are no more - * references to an object. - */ - -int ejsDestroyObj(Ejs *ep, EjsObj *obj) -{ - EjsProperty *pp; - EjsPropLink *lp, *head, *nextLink; - - mprAssert(obj); - - if (obj->destructor) { - EjsVar v; - memset(&v, 0, sizeof(v)); - v.type = EJS_TYPE_OBJECT; - v.objectState = obj; - ejsSetVarName(ep, &v, "destructor"); - -#if BLD_FEATURE_ALLOC_LEAK_TRACK - v.gc.allocatedBy = "static"; -#endif - - if ((obj->destructor)(ep, &v) < 0) { - return -1; - } - } - mprFree(obj->objName); - obj->objName = 0; - - /* - * Just for safety. An object may be marked by a GC on the default - * interpreter. After destroying, it won't be on the free list and so - * won't be reset. - */ - obj->gcMarked = 0; - obj->visited = 0; - - head = &obj->link; - for (lp = head->next; lp != head; lp = nextLink) { - - pp = ejsGetPropertyFromLink(lp); - nextLink = lp->next; - - /* - * We don't unlink as we are destroying all properties. - * If an object, we don't need to clear either. - */ - if (pp->var.type != EJS_TYPE_OBJECT) { - ejsClearVar(ep, ejsGetVarPtr(pp)); - } - ejsFree(ep, pp, EJS_SLAB_PROPERTY); - } - -#if BLD_FEATURE_MULTITHREAD - if (obj->mutex) { - mprDestroyLock(obj->mutex); - } -#endif - - ejsFree(ep, obj, EJS_SLAB_OBJ); - return 0; -} - -/******************************************************************************/ -/* - * Fast hash. The history of this algorithm is part of lost computer science - * folk lore. - */ - -static int hash(const char *property) -{ - uint sum; - - mprAssert(property); - - sum = 0; - while (*property) { - sum += (sum * 33) + *property++; - } - - return sum % EJS_OBJ_HASH_SIZE; -} - -/******************************************************************************/ -/* - * Set a new length for an array. If create is non-null, then it is the name - * of a new array index. If delete is set, it is the name of an index being - * deleted. If setLength is set to a variable, it counts the new length for the - * array. Note that create and delete are ignored if they are non-integer - * array indexes (eg. normal properties). - */ - -void ejsSetArrayLength(Ejs *ep, EjsVar *obj, const char *create, - const char *delete, const EjsVar *setLength) -{ - EjsVar *vp; - char idx[16]; - int oldSize, newSize, i; - - vp = ejsGetPropertyAsVar(ep, obj, "length"); - oldSize = vp->integer; - newSize = oldSize; - - if (create) { - if (isdigit(*create)) { - i = atoi(create); - newSize = max(i + 1, oldSize); - } - } else if (delete) { - if (isdigit(*delete)) { - i = atoi(delete); - newSize = (i == (oldSize - 1) ? oldSize - 1 : oldSize); - } - } else { - newSize = setLength->integer; - } - - for (i = newSize; i < oldSize; i++) { - mprItoa(idx, sizeof(idx), i); - ejsDeleteProperty(ep, obj, idx); - } - - if (ejsWriteVarAsInteger(ep, vp, newSize) == 0) { - mprAssert(0); - } -} - -/******************************************************************************/ - -void ejsClearObjErrors(EjsVar *vp) -{ - if (vp == 0 || vp->type != EJS_TYPE_OBJECT || vp->objectState == 0) { - mprAssert(0); - return; - } - vp->objectState->hasErrors = 0; -} - -/******************************************************************************/ - -int ejsObjHasErrors(EjsVar *vp) -{ - if (vp == 0 || vp->type != EJS_TYPE_OBJECT || vp->objectState == 0) { - mprAssert(0); - return -1; - } - return vp->objectState->hasErrors; -} - -/******************************************************************************/ - -bool ejsIsObjDirty(EjsVar *vp) -{ - mprAssert(vp->type == EJS_TYPE_OBJECT && vp->objectState); - - if (vp->type == EJS_TYPE_OBJECT && vp->objectState) { - return vp->objectState->dirty; - } - return 0; -} - -/******************************************************************************/ - -void ejsResetObjDirtyBit(EjsVar *vp) -{ - mprAssert(vp->type == EJS_TYPE_OBJECT && vp->objectState); - - if (vp->type == EJS_TYPE_OBJECT && vp->objectState) { - vp->objectState->dirty = 0; - } -} - -/******************************************************************************/ -/* - * Copy a string. Always null terminate. - */ - -static int dupString(MPR_LOC_DEC(ctx, loc), uchar **dest, const void *src, - int nbytes) -{ - mprAssert(dest); - mprAssert(src); - - if (nbytes > 0) { - *dest = mprMemdupInternal(MPR_LOC_PASS(ctx, loc), src, nbytes + 1); - if (*dest == 0) { - return MPR_ERR_MEMORY; - } - - } else { - *dest = (uchar*) mprAlloc(ctx, 1); - nbytes = 0; - } - - (*dest)[nbytes] = '\0'; - - return nbytes; -} - -/******************************************************************************/ - -const char *ejsGetVarTypeAsString(EjsVar *vp) -{ - switch (vp->type) { - default: - case EJS_TYPE_UNDEFINED: - return "undefined"; - case EJS_TYPE_NULL: - return "null"; - case EJS_TYPE_BOOL: - return "bool"; - case EJS_TYPE_CMETHOD: - return "cmethod"; - case EJS_TYPE_FLOAT: - return "float"; - case EJS_TYPE_INT: - return "int"; - case EJS_TYPE_INT64: - return "int64"; - case EJS_TYPE_OBJECT: - return "object"; - case EJS_TYPE_METHOD: - return "method"; - case EJS_TYPE_STRING: - return "string"; - case EJS_TYPE_STRING_CMETHOD: - return "string method"; - case EJS_TYPE_PTR: - return "ptr"; - } -} - -/******************************************************************************/ - -void *ejsGetVarUserPtr(EjsVar *vp) -{ - mprAssert(vp); - mprAssert(vp->type == EJS_TYPE_PTR); - - if (!ejsVarIsPtr(vp)) { - return 0; - } - return vp->ptr.userPtr; -} - -/******************************************************************************/ - -void ejsSetVarUserPtr(EjsVar *vp, void *data) -{ - mprAssert(vp); - mprAssert(vp->type == EJS_TYPE_PTR); - - vp->ptr.userPtr = data; -} - -/******************************************************************************/ -/* - * Return TRUE if target is a subclass (or the same class) as baseClass. - */ - -bool ejsIsSubClass(EjsVar *target, EjsVar *baseClass) -{ - do { - if (target->objectState == baseClass->objectState) { - return 1; - } - target = target->objectState->baseClass; - } while (target); - - return 0; -} - -/******************************************************************************/ -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h b/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h deleted file mode 100644 index 071665e00b..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h +++ /dev/null @@ -1,1091 +0,0 @@ -/* - * ejsVar.h -- EJS Universal Variable Type - */ - -/* - * @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 - */ - -/* - * Variables can efficiently store primitive types and can hold references to - * objects. Objects can store properties which are themselves variables. - * Properties can be primitive data types, other objects or methods. - * Properties are indexed by a character name. A variable may store one of - * the following types: - * - * string, integer, integer-64bit, C method, C method with string args, - * Javascript method, Floating point number, boolean value, Undefined - * value and the Null value. - * - * Variables have names while objects may be referenced by multiple variables. - * Objects use reference counting for garbage collection. - * - * This module is not thread safe for performance and compactness. It relies - * on upper modules to provide thread synchronization as required. The API - * provides primitives to get variable/object references or to get copies of - * variables which will help minimize required lock times. - */ - -#ifndef _h_EJS_VAR -#define _h_EJS_VAR 1 - -/********************************* Includes ***********************************/ - -#include "mpr.h" - -/********************************** Defines ***********************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Defined in ejs.h - */ -typedef struct Ejs Ejs; - -/* - * Constants - */ -#if BLD_FEATURE_SQUEEZE - /** - * Maximum property or variable name size - */ - #define EJS_MAX_ID 64 - - /* - * EJS_VAR_HASH_SIZE must be less than the size of the bit field - * propertyIndex in EjsProperty. - */ - #define EJS_OBJ_HASH_SIZE 13 - - /** - * Maximum number of arguments per function call - */ - #define EJS_MAX_ARGS 32 - #define EJS_INC_ARGS 8 /* Frame stack increment */ - -#else - #define EJS_MAX_ID 256 - #define EJS_OBJ_HASH_SIZE 29 - #define EJS_MAX_ARGS 64 - #define EJS_INC_ARGS 8 -#endif - -#define EJS_VAR_MAX_RECURSE 5 /* Max object loops */ - -#if !DOXYGEN -/* - * Forward declare types - */ -struct Ejs; -struct EjsObj; -struct EjsProperty; -struct EjsVar; -#endif - -/** - * @overview EJ primitive variable type - * @description EJ primitive variable values are stored in EjsVar structures. - * The type of the primitive data is described by an EjsType field. - * EjsVar variable types. - * @stability Prototype. - * @library libejs. - * @see EJS_TYPE_UNDEFINED, EJS_TYPE_NULL, EJS_TYPE_BOOL, EJS_TYPE_CMETHOD, - * EJS_TYPE_FLOAT, EJS_TYPE_INT, EJS_TYPE_INT64, EJS_TYPE_OBJECT, - * EJS_TYPE_METHOD, EJS_TYPE_STRING, EJS_TYPE_STRING_CMETHOD, EJS_TYPE_PTR, - */ -typedef uint EjsType; -#define EJS_TYPE_UNDEFINED 0 /**< Undefined. No value has been set */ -#define EJS_TYPE_NULL 1 /**< Value defined to be null. */ -#define EJS_TYPE_BOOL 2 /**< Boolean type. */ -#define EJS_TYPE_CMETHOD 3 /**< C method */ -#define EJS_TYPE_FLOAT 4 /**< Floating point number */ -#define EJS_TYPE_INT 5 /**< Integer number */ -#define EJS_TYPE_INT64 6 /**< 64-bit Integer number */ -#define EJS_TYPE_OBJECT 7 /**< Object reference */ -#define EJS_TYPE_METHOD 8 /**< JavaScript method */ -#define EJS_TYPE_STRING 9 /**< String (immutable) */ -#define EJS_TYPE_STRING_CMETHOD 10 /**< C method with string args */ -#define EJS_TYPE_PTR 11 /**< Opaque pointer */ - -/* - * Create a type for the default number type - * Config.h will define the default number type. For example: - * - * BLD_FEATURE_NUM_TYPE=int - * BLD_FEATURE_NUM_TYPE_ID=EJS_TYPE_INT - */ - -/** - * Set to the type used for EJS numeric variables. Will equate to int, int64 - * or double. - */ -typedef BLD_FEATURE_NUM_TYPE EjsNum; - -/** - * Set to the EJS_TYPE used for EJS numeric variables. Will equate to - * EJS_TYPE_INT, EJS_TYPE_INT64 or EJS_TYPE_FLOAT. - */ -#define EJS_NUM_VAR BLD_FEATURE_NUM_TYPE_ID -#define EJS_TYPE_NUM BLD_FEATURE_NUM_TYPE_ID - -/* - * Return TRUE if a variable is a method type - */ -#define ejsVarIsMethod(vp) \ - ((vp)->type == EJS_TYPE_METHOD || (vp)->type == EJS_TYPE_STRING_CMETHOD || \ - (vp)->type == EJS_TYPE_CMETHOD) - -/* - * Return TRUE if a variable is a numeric type - */ -#define ejsVarIsNumber(vp) \ - ((vp)->type == EJS_TYPE_INT || (vp)->type == EJS_TYPE_INT64 || \ - (vp)->type == EJS_TYPE_FLOAT) - -/* - * Return TRUE if a variable is a boolean - */ -#define ejsVarIsBoolean(vp) \ - ((vp)->type == EJS_TYPE_BOOL) - -/* - * Return TRUE if a variable is an integer type - */ -#define ejsVarIsInteger(vp) ((vp)->type == EJS_TYPE_INT) - -/* - * Return TRUE if a variable is a string - */ -#define ejsVarIsString(vp) \ - ((vp)->type == EJS_TYPE_STRING) - -/* - * Return TRUE if a variable is an object - */ -#define ejsVarIsObject(vp) \ - ((vp)->type == EJS_TYPE_OBJECT) - -/* - * Return TRUE if a variable is a floating number - */ -#define ejsVarIsFloating(vp) \ - ((vp)->type == EJS_TYPE_FLOAT) - -/* - * Return TRUE if a variable is undefined - */ -#define ejsVarIsUndefined(var) \ - ((var)->type == EJS_TYPE_UNDEFINED) - -/* - * Return TRUE if a variable is null - */ -#define ejsVarIsNull(var) \ - ((var)->type == EJS_TYPE_NULL) - -/* - * Return TRUE if a variable is a valid type (not null or undefined) - */ -#define ejsVarIsValid(var) \ - (((var)->type != EJS_TYPE_NULL) && ((var)->type != EJS_TYPE_UNDEFINED)) - -/* - * Return TRUE if a variable is a ptr type - */ -#define ejsVarIsPtr(vp) \ - ((vp)->type == EJS_TYPE_PTR) - -/* MOB -- convert all ep to ejs */ -/** - * @overview C Method signature - * @description This is the calling signature for C Methods. - * @param ejs Ejs reference returned from ejsCreateInterp - * @param thisObj Reference to the "this" object. (The object containing the - * method). - * @param argc Number of arguments. - * @param argv Array of arguments. Each argument is held in an EjsVar type. - * @stability Prototype. - * @library libejs. - * @see ejsCreateCMethodVar - */ -typedef int (*EjsCMethod)(struct Ejs *ejs, struct EjsVar *thisObj, - int argc, struct EjsVar **argv); - -/** - * C Method with string arguments signature - * @overview C Method with string arguments signature - * @description This is the calling signature for C Methods. - * @param ejs Ejs reference returned from ejsCreateInterp - * @param thisObj Reference to the "this" object (object containing the - * method. - * @param argc Number of arguments. - * @param argv Array of arguments. Each argument is held in an C string - * pointer. - * @stability Prototype. - * @library libejs. - * @see ejsCreateStringCMethodVar - */ -typedef int (*EjsStringCMethod)(struct Ejs *ep, struct EjsVar *thisObj, - int argc, char **argv); - -/** - * Flags for types: EJS_TYPE_CMETHOD, EJS_TYPE_STRING_CMETHOD - * NOTE: flags == 0 means to use the EJS handle on method callbacks - */ -/* Use the primary handle on method callbacks */ -#define EJS_PRIMARY_HANDLE 0x1 - -/* Use the alternate handle on method callbacks */ -#define EJS_ALT_HANDLE 0x2 - -/** Method should not create a new local variable block */ -#define EJS_NO_LOCAL 0x4 - -/* Method is a get accessor */ -#define EJS_GET_ACCESSOR 0x8 - -/* Method is a set accessor */ -#define EJS_SET_ACCESSOR 0x10 - -/* - * Flags for E4X (Xml type) - */ -/* Node is a text node */ -#define EJS_XML_FLAGS_TEXT 0x1 - -/* Node is a processing instruction */ -#define EJS_XML_FLAGS_PI 0x2 - -/* Node is a comment */ -#define EJS_XML_FLAGS_COMMENT 0x4 - -/* Node is an attribute */ -#define EJS_XML_FLAGS_ATTRIBUTE 0x8 - -/* Node is an element */ -#define EJS_XML_FLAGS_ELEMENT 0x10 - -/** - * Copy depth - * @overview Specifies how an object should be copied - * @description The EjsCopyDepth type specifies how an object's properties - * should be copied. Several routines take EjsCopyDepth parameters to - * control how the properties of an object should be copied. It provides - * three copy options: - * @see ejsWriteVar - */ -typedef enum EjsCopyDepth { - /** - * During an object copy, object property references will be copied so - * that the original object and the copy will share the same reference to - * a property object. Properties containing primitive types including - * strings will have their values copied and will not share references. - */ - EJS_SHALLOW_COPY, /** Copy strings. Copy object references. */ - /* - * During an object copy, object properties will be replicated so that - * the original object and the copy will not share references to the same - * object properties. If the original object's properties are themselves - * objects, their properties will not be copied. Only their references - * will be copied. i.e. the deep copy is one level deep. - */ - EJS_DEEP_COPY, /** Copy strings and copy object contents. */ - /* - * During an object copy, all object properties will be replicated so that - * the original object and the copy will not share references to the same - * object properties. If the original object's properties are themselves - * objects, their properties will be copied. i.e. the copy is of infinite - * depth. - */ - EJS_RECURSIVE_DEEP_COPY /** Copy strings and copy object contents - recursively (complete copy). */ -} EjsCopyDepth; - - -/* - * Enumeration flags - */ -/** Enumerate data properties */ -#define EJS_ENUM_DATA 0x0 - -/** Enumerate sub classes */ -#define EJS_ENUM_CLASSES 0x1 - -/** Enumerate non-enumerable properties */ -#define EJS_ENUM_HIDDEN 0x2 - -/** Enumerate all properties */ -#define EJS_ENUM_ALL (0x3) - -/** Magic number when allocated */ -#define EJS_MAGIC 0xe801e2ec -#define EJS_MAGIC_FREE 0xe701e3ea - - -/* - * Garbage Collection Linkage. Free list only uses the next pointers. - */ -typedef struct EjsGCLink { -#if BLD_DEBUG - uint magic; /* Magic number */ -#endif -#if BLD_FEATURE_ALLOC_LEAK_TRACK - const char *allocatedBy; /* Who allocated this */ -#endif - struct EjsGCLink *next; /* Next property */ -} EjsGCLink; - - -/** - * @overview EJS Variable Type - * @description The EJ language supports an extensive set of primitive types. - * These variable types can efficiently store primitive data types such as - * integers, strings, binary string, booleans, floating point numbers, - * pointer references, and objects. EjsVars are the universal type used by - * EJ to hold objects, classes and properties. - * \n\n - * An EjsVar may store one of the following types: - * @li Boolean - * @li Floating point (if supported in this build) - * @li Integer - * @li 64 bit integer (if supported in this build) - * @li String - * @li Binary string - * @li C function or C++ method - * @li C function with string args - * @li Javascript method - * @li Object - * @li Null value. - * @li Undefined value - * \n\n - * Objects can hold object properties which are themselves EJS variables. - * Properties are hash indexed by the property name and are stored in - * an ordered sequence. i.e. Order of properties is maintained. Objects may - * be referenced by multiple variables and they use garbage collection to - * reclaim memory no longer in use by objects and properties. - * - * @warning This module is @e not thread safe for performance and - * compactness. It relies on upper modules to provide thread - * synchronization as required. The API provides primitives to get - * variable/object references or to get copies of variables which should - * help minimize required lock times. - * @stability Prototype. - * @library libejs - * @see Ejs, EjsProperty, ejsCreateStringVar, ejsFreeVar - */ - -typedef struct EjsVar { /* Size 12 bytes */ - /* - * GC must be first - */ -#if BLD_DEBUG || BLD_FEATURE_ALLOC_LEAK_TRACK - EjsGCLink gc; /* Garbage collection links */ -#endif - -#if BLD_DEBUG - const char *propertyName; /* Ptr to property name */ -#endif - - /* - * Union of primitive types. When debugging on Linux, don't use unions - * as the gdb debugger can't display them. - */ -#if (!BLD_DEBUG && !VXWORKS) || WIN || BREW_SIMULATOR - union { -#endif - /* - * For debugging, we order the common types first - */ - struct EjsObj *objectState; /* Object state information */ - int integer; - bool boolean; - -#if BLD_FEATURE_FLOATING_POINT - double floating; -#endif -#if BLD_FEATURE_INT64 - int64 integer64; -#endif - - struct { - int length; /* String length (sans null) */ - /* - * All strings always have a trailing null allocated - */ - union { - char *string; /* String */ - uchar *ustring; /* Binary string */ - }; - }; - - struct { /* Javascript methods */ - MprArray *args; /* Null terminated */ - char *body; - } method; - - struct { /* Method with EjsVar args */ - EjsCMethod fn; /* Method pointer */ - void *userData; /* User data for method */ - } cMethod; - - struct { /* Method with string args */ - EjsStringCMethod fn; /* Method pointer */ - void *userData; /* User data for method */ - } cMethodWithStrings; - - struct { - void *userPtr; /* Opaque pointer */ - int (*destructor)(Ejs *ejs, struct EjsVar *vp); - } ptr; - -#if (!BLD_DEBUG && !VXWORKS) || WIN || BREW_SIMULATOR - }; -#endif - - /* - * Packed bit field (32 bits) - */ - uint flags : 8; /* Type specific flags */ - EjsType type : 4; /* Selector into union */ - uint stringLen : 4; /* Length of string if inline */ - uint allocatedData : 1; /* Node needs freeing */ - uint isArray : 1; /* Var is an array */ - uint isArrayLength : 1; /* Var is array.length */ - uint callsSuper : 1; /* Method calls super() */ - uint isProperty : 1; /* Part of a property */ - uint reserved : 11; /* Unused */ - -} EjsVar; - - -/* - * Linkage for the ordered list of properties - */ -typedef struct EjsPropLink { - struct EjsPropLink *next; /* Next property */ - struct EjsPropLink *prev; /* Previous property */ - - /* - * To make debugging easier - */ -#if BLD_DEBUG - const char *propertyName; /* Pointer to name */ - struct EjsProperty *property; /* Pointer to property */ - struct EjsPropLink *head; /* Dummy head of list */ -#endif -} EjsPropLink; - - -/** - * @overview Object Property Type - * @description The EjsProperty type is used to store all object properties. - * It contains the property name, property linkage, propery attributes - * such as public/private, enumerable and readonly settings. It also - * contains an EjsVar to store the property data value. - * @stability Prototype. - * @library libejs - * @see Ejs, EjsVar - */ -typedef struct EjsProperty { /* Size 96 bytes in squeeze */ - /* - * EjsVar must be first. We often take the address of "var" and take - * advantage of if an EjsProperty is null, then &prop->var will be null - * also. Be WARNED. External users should use ejsGetVarPtr and - * ejsGetPropertyPtr to convert between the two. - */ - EjsVar var; /* Property value */ - - /* OPT change this to a pointer to the base class property */ - char name[EJS_MAX_ID]; /* Name */ - - uint visited : 1; /* Has been traversed */ - uint isPrivate : 1; /* Property is private */ - uint isProtected : 1; /* Property is protected */ - uint dontEnumerate : 1; /* Not enumerable */ - uint dontDelete : 1; /* Prevent delete */ - uint readonly : 1; /* Unmodifiable */ - uint allowNonUnique : 1; /* Multiple of same name ok */ - uint delayedDelete : 1; - uint reserved : 24; - - EjsPropLink link; /* Ordered linked list */ - struct EjsProperty *hashNext; /* Hash table linkage */ - - /* MOB -- is this really required */ - struct EjsObj *parentObj; /* Pointer to parent object */ - -} EjsProperty; - - -#define EJS_OP_DOT 0x1 -#define EJS_OP_INDEX 0x2 -#define EJS_OP_PLUS 0x3 -#define EJS_OP_MINUS 0x4 -#define EJS_OP_MULTIPLY 0x5 -#define EJS_OP_DIVIDE 0x6 -#define EJS_OP_CALL 0x7 - -typedef struct EjsOp { - int opType; - -} EjsOp; - -/* - * Propety Access Methods. Used per class. - * MOB -- rename EjsHelpers - */ -typedef struct EjsMethods { -#if FUTURE - int (*create)(Ejs *ep, EjsVar *thisObj); - int (*deleteProperty)(Ejs *ep, EjsVar *thisObj, const char *prop); - EjsVar *(*getProperty)(Ejs *ep, EjsVar *thisObj, const char *prop); - EjsVar *(*setProperty)(Ejs *ep, EjsVar *thisObj, const char *prop); - int (*hasProperty)(Ejs *ep, EjsVar *thisObj, const char *prop); - int (*hasInstance)(Ejs *ep, EjsVar *thisObj, const char *prop); - int (*operate)(Ejs *ep, EjsVar *thisObj, EjsOp op, EjsVar *result, - EjsVar *lhs, EjsVar *rhs, int *code); -#else - - EjsVar *(*createProperty)(Ejs *ep, EjsVar *obj, const char *property); - int (*deleteProperty)(Ejs *ep, EjsVar *obj, const char *property); - EjsVar *(*getProperty)(Ejs *ep, EjsVar *obj, const char *property); - EjsVar *(*setProperty)(Ejs *ep, EjsVar *obj, const char *property, - const EjsVar *value); - /* - * Other implemented internal properties in ECMA-262 are: - * - * [[Construct]] implemented via EjsVar methods - * [[Prototype]] implemented via EjsObj->baseClass - * [[Class]] implemented via EjsObj->baseClass->name - * [[Value]] Implemented via EjsProperty + EjsVar + EjsObj - */ - - /* - * FUTURE -- not implemented - */ - int (*canPut)(Ejs *ep, EjsVar *obj, const char *property); - int (*defaultValue)(Ejs *ep, EjsVar *obj, const char *property, - const char *hint); - int (*hasProperty)(Ejs *ep, EjsVar *obj, const char *property); - EjsVar *(*call)(Ejs *ep, EjsVar *obj, const char *property, - EjsVar *args); - int (*hasInstance)(Ejs *ep, EjsVar *obj, const char *property); - int (*scope)(Ejs *ep, EjsVar *obj, const char *property); - int (*match)(Ejs *ep, EjsVar *obj, const char *property, - const char *string, int index); -#endif -} EjsMethods; - - -/* - * Ejs Object Type - */ -typedef struct EjsObj { - /* - * GC must be first - */ - EjsGCLink gc; /* Garbage collection links */ - - union { - char *objName; /* Object name */ - char *className; /* Class name */ - }; - - struct EjsVar *baseClass; /* Pointer to base class object */ - - EjsPropLink link; /* Ordered list of properties */ - - /* OPT -- dynamically allocate this only if required */ - EjsProperty *propertyHash[EJS_OBJ_HASH_SIZE]; /* Hash chains */ - - /* OPT -- could save this and store off baseClass only */ - EjsMethods *methods; /* Property access methods */ - void *nativeData; /* Native object data */ - - int (*destructor)(Ejs *ejs, struct EjsVar *vp); - - uint numProperties : 16; /* Total count of items */ - uint visited : 1; /* Has been traversed */ - uint gcMarked : 1; /* Node marked in-use by GC */ - uint permanent : 1; /* Permanent object, dont GC */ - uint alive : 1; /* Only GC if alive */ - uint noConstructor : 1; /* Object has no constructor */ - uint dirty : 1; /* Object has been modified */ - uint hasErrors : 1; /* Update error */ - uint preventDeleteProp : 1; /* Don't allow prop deletion */ - uint delayedDeleteProp : 1; /* Delayed delete of props */ - uint reserved : 7; /* Unused */ - - Ejs *ejs; /* Owning interp */ - -#if BLD_FEATURE_MULTITHREAD - MprLock *mutex; /* Advisory mutex lock */ -#endif -} EjsObj; - - -/* - * Define a field macro so code an use numbers in a "generic" fashion. - */ -#if EJS_NUM_VAR == EJS_TYPE_INT || DOXYGEN -/* - * Default numeric type - */ -#define ejsNumber integer -#endif -#if EJS_NUM_VAR == EJS_TYPE_INT64 -/* Default numeric type */ -#define ejsNumber integer64 -#endif -#if EJS_NUM_VAR == EJS_TYPE_FLOAT -/* Default numeric type */ -#define ejsNumber floating -#endif - -typedef BLD_FEATURE_NUM_TYPE EjsNumber; - -/* - * Memory allocation slabs - */ -#define EJS_SLAB_OBJ 0 -#define EJS_SLAB_PROPERTY 1 -#define EJS_SLAB_VAR 2 -#define EJS_SLAB_MAX 3 - -/** - * Object and pointer property destructory type - */ -typedef int (*EjsDestructor)(Ejs *ejs, EjsVar *vp); - -#if BLD_FEATURE_ALLOC_LEAK_TRACK || DOXYGEN -/* - * Line number information args and declarations for ejsAlloc. - * Use EJS_LOC_ARGS in normal user code. - * Use EJS_LOC_DEC in declarations. - * Use EJS_LOC_PASS in layered APIs to pass original line info down. - */ -#define EJS_LOC_ARGS(ejs) ejs, MPR_LOC -#define EJS_LOC_DEC(ejs, loc) Ejs *ejs, const char *loc -#define EJS_LOC_PASS(ejs, loc) ejs, loc -#else -#define EJS_LOC_ARGS(ejs) ejs -#define EJS_LOC_DEC(ejs, loc) Ejs *ejs -#define EJS_LOC_PASS(ejs, loc) ejs -#endif - -/******************************* Internal Prototypes **************************/ - -#define ejsInitVar(vp, varType) \ - if (1) { \ - (vp)->type = varType; \ - (vp)->isArray = 0; \ - (vp)->flags = 0; \ - } else -extern void ejsClearVar(Ejs *ep, EjsVar *vp); - -extern int ejsDestroyObj(Ejs *ep, EjsObj *obj); -extern EjsVar *ejsCreatePropertyMethod(Ejs *ep, EjsVar *obj, - const char *name); -extern EjsVar *ejsSetPropertyMethod(Ejs *ep, EjsVar *obj, const char *name, - const EjsVar *value); -extern EjsVar *ejsGetPropertyMethod(Ejs *ep, EjsVar *obj, const char *name); -extern int ejsDeletePropertyMethod(Ejs *ep, EjsVar *obj, - const char *name); -extern void ejsSetArrayLength(Ejs *ep, EjsVar *obj, const char *creating, - const char *deleting, const EjsVar *setLength); - -/* - * At the moment, these are the same routine - */ -extern void ejsSetClassName(Ejs *ep, EjsVar *obj, const char *name); -#define ejsSetObjName ejsSetObjName - -extern bool ejsIsObjDirty(EjsVar *vp); -extern void ejsResetObjDirtyBit(EjsVar *vp); - -extern int ejsObjHasErrors(EjsVar *vp); -extern void ejsClearObjErrors(EjsVar *vp); - -extern EjsVar *ejsClearProperty(Ejs *ep, EjsVar *obj, const char *prop); - -typedef int (*EjsSortFn)(Ejs *ep, EjsProperty *p1, EjsProperty *p2, - const char *propertyName, int order); -extern void ejsSortProperties(Ejs *ep, EjsVar *obj, EjsSortFn fn, - const char *propertyName, int order); - -#if BLD_DEBUG -#define ejsSetVarName(ep, vp, varName) \ - if (1) { \ - (vp)->propertyName = varName; \ - if ((vp)->type == EJS_TYPE_OBJECT && \ - (vp)->objectState && \ - ((vp)->objectState->objName == 0)) { \ - (vp)->objectState->objName = \ - mprStrdup(ep, varName); \ - } \ - } else -#else -#define ejsSetVarName(ep, vp, varName) -#endif - -EjsVar *ejsFindProperty(Ejs *ep, EjsVar **obj, char **property, - EjsVar *global, EjsVar *local, const char *fullName, - int create); - -extern EjsVar *ejsCopyProperties(Ejs *ep, EjsVar *dest, - const EjsVar *src, EjsCopyDepth copyDepth); - -#define EJS_LINK_OFFSET ((uint) (&((EjsProperty*) 0)->link)) -#define ejsGetPropertyFromLink(lp) \ - ((EjsProperty*) ((char*) lp - EJS_LINK_OFFSET)) - -#define ejsGetObjPtr(vp) ((EjsObj*) vp->objectState) - -extern void ejsMakePropertyPrivate(EjsProperty *pp, int isPrivate); -extern void ejsMakePropertyReadOnly(EjsProperty *pp, int readonly); -extern void ejsMakePropertyUndeleteable(EjsProperty *pp, int deletable); -extern int ejsMakeObjLive(EjsVar *vp, bool alive); -extern void ejsMakeClassNoConstructor(EjsVar *vp); - -extern bool ejsBlockInUseInt(EjsVar *vp); -#if BLD_DEBUG - #define ejsBlockInUse(vp) ejsBlockInUseInt(vp) -#else - #define ejsBlockInUse(vp) -#endif - -/********************************* Prototypes *********************************/ - -/* - * Variable constructors and destructors - */ -extern EjsVar *ejsCreateBinaryStringVar(Ejs *ep, const uchar *value, - int len); -extern EjsVar *ejsCreateBoolVar(Ejs *ep, int value); -extern EjsVar *ejsCreateCMethodVar(Ejs *ep, EjsCMethod fn, - void *userData, int flags); -#if BLD_FEATURE_FLOATING_POINT -extern EjsVar *ejsCreateFloatVar(Ejs *ep, double value); -#endif -extern EjsVar *ejsCreateIntegerVar(Ejs *ep, int value); -#if BLD_FEATURE_INT64 -extern EjsVar *ejsCreateInteger64Var(Ejs *ep, int64 value); -#endif - -extern EjsVar *ejsCreateMethodVar(Ejs *ep, const char *body, - MprArray *args, int flags); -extern EjsVar *ejsCreateNullVar(Ejs *ep); -extern EjsVar *ejsCreateNumberVar(Ejs *ep, EjsNumber value); - -#define ejsCreateObjVar(ep) \ - ejsCreateObjVarInternal(EJS_LOC_ARGS(ep)) -extern EjsVar *ejsCreateObjVarInternal(EJS_LOC_DEC(ep, loc)); - -extern EjsVar *ejsCreatePtrVar(Ejs *ep, void *ptr, EjsDestructor dest); - -extern EjsVar *ejsCreateStringCMethodVar(Ejs *ep, EjsStringCMethod fn, - void *userData, int flags); - -#define ejsCreateStringVar(ep, value) \ - ejsCreateStringVarInternal(EJS_LOC_ARGS(ep), value) -extern EjsVar *ejsCreateStringVarInternal(EJS_LOC_DEC(ep, loc), - const char *value); - -extern EjsVar *ejsCreateUndefinedVar(Ejs *ep); - -/* MOB -- naming. Should be Create/Destroy */ -extern void ejsFreeVar(Ejs *ep, EjsVar *vp); - -/* - * Var support routines - */ -extern int ejsGetVarFlags(EjsVar *vp); -extern void ejsSetVarFlags(EjsVar *obj, int flags); - -extern EjsType ejsGetVarType(EjsVar *vp); -extern const char *ejsGetVarTypeAsString(EjsVar *vp); - -extern void *ejsGetCMethodUserData(EjsVar *obj); -extern void ejsSetCMethodUserData(EjsVar *obj, void *userData); - -extern void *ejsGetVarUserPtr(EjsVar *vp); -extern void ejsSetVarUserPtr(EjsVar *vp, void *data); - - -/* - * Variable access and manipulation. These work on standalone objects. - */ -#define ejsDupVar(ep, src, copyDepth) \ - ejsDupVarInternal(EJS_LOC_ARGS(ep), src, copyDepth) -extern EjsVar *ejsDupVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *src, - EjsCopyDepth copyDepth); -#define ejsWriteVar(ep, dest, src, copyDepth) \ - ejsWriteVarInternal(EJS_LOC_ARGS(ep), dest, src, copyDepth) -extern EjsVar *ejsWriteVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *dest, - const EjsVar *src, EjsCopyDepth copyDepth); -extern EjsVar *ejsWriteVarAsBinaryString(Ejs *ep, EjsVar *dest, - const uchar *value, int len); -extern EjsVar *ejsWriteVarAsBoolean(Ejs *ep, EjsVar *dest, bool value); -extern EjsVar *ejsWriteVarAsCMethod(Ejs *ep, EjsVar *dest, EjsCMethod fn, - void *userData, int flags); -#if BLD_FEATURE_FLOATING_POINT -extern EjsVar *ejsWriteVarAsFloat(Ejs *ep, EjsVar *dest, double value); -#endif -extern EjsVar *ejsWriteVarAsInteger(Ejs *ep, EjsVar *dest, int value); -#if BLD_FEATURE_INT64 -extern EjsVar *ejsWriteVarAsInteger64(Ejs *ep, EjsVar *dest, int64 value); -#endif -extern EjsVar *ejsWriteVarAsMethod(Ejs *ep, EjsVar *dest, - const char *body, MprArray *args); -extern EjsVar *ejsWriteVarAsNull(Ejs *ep, EjsVar *dest); -extern EjsVar *ejsWriteVarAsNumber(Ejs *ep, EjsVar *dest, EjsNum value); -#define ejsWriteVarAsString(ep, dest, value) \ - ejsWriteVarAsStringInternal(EJS_LOC_ARGS(ep), dest, value) -extern EjsVar *ejsWriteVarAsStringInternal(EJS_LOC_DEC(ep, loc), - EjsVar *dest, const char *value); -extern EjsVar *ejsWriteVarAsStringCMethod(Ejs *ep, EjsVar *dest, - EjsStringCMethod fn, void *userData, int flags); -extern EjsVar *ejsWriteVarAsUndefined(Ejs *ep, EjsVar *dest); - -/* - * These routines do not convert types - */ -/* MOB -- make this a fn and pass back the length as an arg */ -#define ejsReadVarAsBinaryString(vp) ((const uchar*) (vp->ustring)); -#define ejsReadVarAsBoolean(vp) (vp->boolean); -#define ejsReadVarAsCMethod(vp) (vp->cMethod); -#if BLD_FEATURE_FLOATING_POINT -#define ejsReadVarAsFloat(vp) (vp->floating); -#endif -#define ejsReadVarAsInteger(vp) (vp->integer); -#if BLD_FEATURE_INT64 -#define ejsReadVarAsInteger64(vp) (vp->int64); -#endif -#define ejsReadVarAsString(vp) ((const char*) (vp->string)); -#define ejsReadVarAsStringCMethod(vp) (vp->cMethodWithStrings); -/* MOB -- remove this fn */ -#define ejsReadVarStringLength(vp) (vp->length); - -/* - * Object property creation routines - */ -extern EjsProperty *ejsCreateProperty(Ejs *ep, EjsVar *obj, const char *prop); -extern EjsProperty *ejsCreateSimpleProperty(Ejs *ep, EjsVar *obj, - const char *prop); -extern EjsProperty *ejsCreateSimpleNonUniqueProperty(Ejs *ep, EjsVar *obj, - const char *prop); -/* MOB -- should be destroy */ -extern int ejsDeleteProperty(Ejs *ep, EjsVar *obj, const char *prop); - - -/* - * Get property routines - */ -extern EjsProperty *ejsGetProperty(Ejs *ep, EjsVar *obj, const char *prop); -extern EjsProperty *ejsGetSimpleProperty(Ejs *ep, EjsVar *obj, - const char *prop); - -extern EjsVar *ejsGetPropertyAsVar(Ejs *ep, EjsVar *obj, - const char *prop); -extern int ejsGetPropertyCount(EjsVar *obj); - -extern const uchar *ejsGetPropertyAsBinaryString(Ejs *ep, EjsVar *obj, - const char *prop, int *length); -extern bool ejsGetPropertyAsBoolean(Ejs *ep, EjsVar *obj, - const char *prop); -extern int ejsGetPropertyAsInteger(Ejs *ep, EjsVar *obj, - const char *prop); -extern int64 ejsGetPropertyAsInteger64(Ejs *ep, EjsVar *obj, - const char *prop); -extern EjsNum ejsGetPropertyAsNumber(Ejs *ep, EjsVar *obj, - const char *prop); -extern void *ejsGetPropertyAsPtr(Ejs *ep, EjsVar *obj, - const char *prop); -extern const char *ejsGetPropertyAsString(Ejs *ep, EjsVar *obj, - const char *prop); - -/* - * Object property update routines - */ -extern EjsProperty *ejsSetBaseProperty(Ejs *ep, EjsVar *obj, const char *prop, - const EjsVar *value); -extern EjsProperty *ejsSetProperty(Ejs *ep, EjsVar *obj, const char *prop, - const EjsVar *value); -extern EjsProperty *ejsSetPropertyAndFree(Ejs *ep, EjsVar *obj, - const char *prop, EjsVar *value); -extern EjsProperty *ejsSetPropertyToBinaryString(Ejs *ep, EjsVar *obj, - const char *prop, const uchar *value, int len); -extern EjsProperty *ejsSetPropertyToBoolean(Ejs *ep, EjsVar *obj, - const char *prop, bool value); -extern EjsProperty *ejsSetPropertyToCMethod(Ejs *ep, EjsVar *obj, - const char *prop, EjsCMethod fn, void *userData, - int flags); -#if BLD_FEATURE_FLOATING_POINT -extern EjsProperty *ejsSetPropertyToFloat(Ejs *ep, EjsVar *obj, - const char *prop, double value); -#endif -extern EjsProperty *ejsSetPropertyToInteger(Ejs *ep, EjsVar *obj, - const char *prop, int value); -#if BLD_FEATURE_INT64 -extern EjsProperty *ejsSetPropertyToInteger64(Ejs *ep, EjsVar *obj, - const char *prop, int64 value); -#endif -extern EjsProperty *ejsSetPropertyToMethod(Ejs *ep, EjsVar *obj, - const char *prop, const char *body, MprArray *args, - int flags); -extern EjsProperty *ejsSetPropertyToNewObj(Ejs *ep, EjsVar *obj, - const char *prop, const char *className, - MprArray *args); -extern EjsProperty *ejsSetPropertyToNull(Ejs *ep, EjsVar *obj, - const char *prop); -extern EjsProperty *ejsSetPropertyToNumber(Ejs *ep, EjsVar *obj, - const char *prop, EjsNum value); -extern EjsProperty *ejsSetPropertyToObj(Ejs *ep, EjsVar *obj, - const char *prop); -extern EjsProperty *ejsSetPropertyToPtr(Ejs *ep, EjsVar *obj, - const char *prop, void *ptr, EjsDestructor destructor); - -extern EjsProperty *ejsSetPropertyToStringCMethod(Ejs *ep, EjsVar *obj, - const char *prop, EjsStringCMethod fn, - void *userData, int flags); -extern EjsProperty *ejsSetPropertyToString(Ejs *ep, EjsVar *obj, - const char *prop, const char *value); -extern EjsProperty *ejsSetPropertyToUndefined(Ejs *ep, EjsVar *obj, - const char *prop); - - -/* Convenience function */ -extern EjsVar *ejsSetPropertyToObjAsVar(Ejs *ep, EjsVar *obj, - const char *prop); -extern void ejsSetObjDestructor(Ejs *ep, EjsVar *obj, - EjsDestructor destructor); -extern void ejsClearObjDestructor(Ejs *ep, EjsVar *obj); - -/* - * Enumeration of properties - * MOB -- should these take an ejs parameter to be consistent - */ -extern EjsProperty *ejsGetFirstProperty(const EjsVar *obj, int flags); -extern EjsProperty *ejsGetNextProperty(EjsProperty *last, int flags); - -/* - * Method definition and control. - */ -extern EjsProperty *ejsDefineMethod(Ejs *ep, EjsVar *obj, const char *prop, - const char *body, MprArray *args); -extern EjsProperty *ejsDefineCMethod(Ejs *ep, EjsVar *obj, const char *prop, - EjsCMethod fn, int flags); - -extern EjsProperty *ejsDefineStringCMethod(Ejs *ep, EjsVar *obj, - const char *prop, EjsStringCMethod fn, int flags); - -extern EjsProperty *ejsDefineAccessors(Ejs *ep, EjsVar *obj, - const char *prop, const char *getBody, - const char *setBody); -extern EjsProperty *ejsDefineCAccessors(Ejs *ep, EjsVar *obj, - const char *prop, EjsCMethod getFn, EjsCMethod setFn, - int flags); - -/* - * Macro to get the variable value portion of a property - */ -#define ejsGetVarPtr(pp) (&((pp)->var)) -#define ejsGetPropertyPtr(vp) ((EjsProperty*) vp) - -/* MOB -- take ejs to be consistent */ -extern int ejsMakePropertyEnumerable(EjsProperty *pp, bool enumerable); -extern int ejsMakeObjPermanent(EjsVar *vp, bool permanent); - - -/* - * Var conversion routines - * MOB -- should these take an Ejs as first arg for consistency - */ -extern bool ejsVarToBoolean(EjsVar *vp); -#if BLD_FEATURE_FLOATING_POINT -extern double ejsVarToFloat(EjsVar *vp); -#endif -extern int ejsVarToInteger(EjsVar *vp); -#if BLD_FEATURE_INT64 -extern int64 ejsVarToInteger64(EjsVar *vp); -#endif -extern EjsNum ejsVarToNumber(EjsVar *vp); -extern char *ejsVarToString(Ejs *ep, EjsVar *vp); -extern char *ejsVarToStringEx(Ejs *ep, EjsVar *vp, bool *alloc); -extern char *ejsFormatVar(Ejs *ep, const char *fmt, EjsVar *vp); - -#if BLD_FEATURE_FLOATING_POINT -extern double ejsParseFloat(const char *str); -#endif -/* - * Parsing and type range checking routines - */ -extern bool ejsParseBoolean(const char *str); -extern int ejsParseInteger(const char *str); -#if BLD_FEATURE_INT64 -extern int64 ejsParseInteger64(const char *str); -#endif -extern EjsNum ejsParseNumber(const char *str); -extern EjsVar *ejsParseVar(Ejs *ep, const char *str, EjsType prefType); - -#if BLD_FEATURE_FLOATING_POINT -extern bool ejsIsInfinite(double f); -extern bool ejsIsNan(double f); -#endif - -/* - * Advisory locking support - */ -#if BLD_FEATURE_MULTITHREAD -extern void ejsLockObj(EjsVar *vp); -extern void ejsUnlockObj(EjsVar *vp); -#endif - -/* - * Just for debugging - */ -extern bool ejsObjIsCollectable(EjsVar *vp); - -#ifdef __cplusplus -} -#endif - -/*****************************************************************************/ -#endif /* _h_EJS_VAR */ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/lib/event.js b/source4/lib/appweb/ejs-2.0/ejs/lib/event.js deleted file mode 100644 index 283a3ec72f..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/lib/event.js +++ /dev/null @@ -1,141 +0,0 @@ -/* - * @file event.js - * @brief Event class - * @copy Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - * - * Usage: - * listener = new System.Listener(); - * listener.onClick = function() { - * // Any code here - * } - * eventTarget.addListener(eventName, listener); - * or - * listener = new System.Listener(obj, method); - * eventTarget.addListener(eventName, listener); - * - * To fire events: - * eventTarget.fire(eventName, new System.Event("My Event")); - */ - -/******************************************************************************/ -/* - * Base event class - */ -class System.Event -{ - var type; // keyboard - var timeStamp; - var arg; - - /* MOB -- constructor should take a type */ - function Event(arg) - { - timeStamp = time(); - type = "default"; - this.arg = arg; - } -} - -/* MOB -- should not be needed */ -Event = System.Event; - -class System.Listener -{ - var obj; - var method; - - function Listener(obj, method) - { - if (arguments.length >= 1) { - this.obj = obj; - } else { - this.obj = this; - } - if (arguments.length == 2) { - this.method = method; - } else { - this.method = "onEvent"; - } - } -} -/* MOB -- should not be needed */ -Listener = System.Listener; - - -/* - * The Event target class - */ -class System.EventTarget -{ - // Private - var events; /* Hash of a event names */ - - function EventTarget() - { - events = new Object(); - } - - // Public - function addListener(eventName, listener) - { - var listeners = events[eventName]; - if (listeners == undefined) { - listeners = events[eventName] = new Array(); - } - if (arguments.length == 2) { - var method = eventName; - } - /* MOB OPT */ - for (var i = 0; i < listeners.length; i++) { - var l = listeners[i]; - if (l == listener) { - return; - } - } - listeners[listeners.length] = listener; - } - - function removeListener(eventName, listener) - { - var listeners = events[eventName]; - - if (listeners == undefined) { - return; - } - - for (var i = 0; i < listeners.length; i++) { - var l = listeners[i]; - if (l == listener) { - // MOB -- want listeners.splice here - // listeners.splice(i, 1); - for (var j = i; j < (listeners.length - 1); j++) { - listeners[j] = listeners[j + 1]; - } - delete listeners[listeners.length - 1]; - i = listeners.length; - } - } - } - - function fire(eventName, event) - { - var listeners = events[eventName]; - - if (listeners == undefined) { - // println("Event.fire(): unknown eventName " + eventName); - return; - } - - for (var i = listeners.length - 1; i >= 0; i--) { - var listener = listeners[i]; - var method = listener.obj[listener.method]; - if (method == undefined) { - throw new EvalError("Undefined method: " + listener.method); - } - listener.obj[listener.method](listener, event); - } - } -} - -/* MOB -- should not be needed */ -EventTarget = System.EventTarget; diff --git a/source4/lib/appweb/ejs-2.0/ejs/lib/global.js b/source4/lib/appweb/ejs-2.0/ejs/lib/global.js deleted file mode 100644 index f2daaa57c0..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/lib/global.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * @file global.js - * @brief Misc global functions - * @copy Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - */ - -/******************************************************************************/ - -function min(a, b) -{ - if (a < b) { - return a; - } else { - return b; - } -} - - -function max(a, b) -{ - if (a > b) { - return a; - } else { - return b; - } -} - -function abs(a) -{ - if (a < 0) { - return -a; - } - return a; -} diff --git a/source4/lib/appweb/ejs-2.0/ejs/lib/startup.js b/source4/lib/appweb/ejs-2.0/ejs/lib/startup.js deleted file mode 100644 index e627a96e04..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/lib/startup.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * @file startup.js - * @brief Embedded JavaScript Startup Code - * @copy Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - * - * Invoked automatically on startup. - */ - -/******************************************************************************/ - -// println("Loading startup.js ..."); - -include("lib/event.js"); -include("lib/global.js"); -include("lib/timer.js"); diff --git a/source4/lib/appweb/ejs-2.0/ejs/lib/timer.js b/source4/lib/appweb/ejs-2.0/ejs/lib/timer.js deleted file mode 100644 index f4cb8b12ce..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/lib/timer.js +++ /dev/null @@ -1,158 +0,0 @@ -/* - * @file timer.js - * @brief Timer class - * @copy Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - * - * Usage: - * timer = new System.Timer("name", period); - * timer.onTick = function(arg) { - * // Anything here - * } - * timer.start(); - * or - * - * timer = new System.Timer("name", period, obj, method); - * timer.start(); - */ - -/******************************************************************************/ - -class System.Timer -{ - var id; - - /* MOB -- really need accessor on period. If user updates period, - then due must be updated. */ - var period; - var due; - var runOnce; // Run timer just once - var method; // Callback method - var obj; // Callback object - - function Timer(id, period, obj, method) - { - this.id = id; - this.period = period; - due = time() + period; - - if (arguments.length >= 3) { - this.obj = obj; - } else { - this.obj = this; - } - if (arguments.length >= 4) { - this.method = method; - } else { - this.method = "onTick"; - } - } - - /* MOB this should be deprecated */ - function reschedule(period) - { - /* MOB -- should update the timer service somehow */ - this.period = period; - } - - function run(now) - { - if (obj[method] == undefined) { - trace("Timer cant find timer method " + method); - due = now + this.period; - return; - } - - /* - * Run the timer - */ - try { - obj[method](this); - } - catch (error) { - trace("Timer exception: " + error); - } - - if (runOnce) { - timerService.removeTimer(this); - - } else { - due = now + this.period; - } - } - - function start() - { - if (obj[method] == undefined) { - throw new Error("Callback method is undefined"); - } else { - timerService.addTimer(this); - } - } - - function stop() - { - timerService.removeTimer(this); - } - -} - -/* MOB -- should not need this */ -Timer = System.Timer; - - -/* - * Timer service - */ -class System.TimerService -{ - var timers; - var nextDue; - - function TimerService() - { - timers = new Object(); - nextDue = 0; - global.timerService = this; - } - - function addTimer(timer) - { - timers[timer.id] = timer; - } - - function removeTimer(timer) - { - try { - delete timers[timer.id]; - } - catch {} - } - - function getIdleTime() - { - return nextDue - time(); - } - - function runTimers() - { - var now = time(); - - nextDue = 2147483647; /* MOB -- MATH.MAX_INT; */ - - for each (var timer in timers) - { - if (timer.due < now) { - timer.run(now); - } - } - for each (var timer in timers) - { - if (timer.due < nextDue) { - nextDue = timer.due; - } - } - // println("runTimers leaving with " + (nextDue - now)); - return nextDue - time(); - } -} -TimerService = System.TimerService; diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/.ignore b/source4/lib/appweb/ejs-2.0/ejs/system/.ignore deleted file mode 100755 index fb5a29031e..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/.ignore +++ /dev/null @@ -1 +0,0 @@ -.updated diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/Makefile b/source4/lib/appweb/ejs-2.0/ejs/system/Makefile deleted file mode 100755 index 2d83662655..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# Makefile to build the EJS Object Model -# -# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. -# - -COMPILE := *.c -EXPORT_OBJECTS := yes -MAKE_IFLAGS := -I.. -I../../mpr -I../../exml - -include make.dep - -ifeq ($(BLD_HOST_UNIX),1) -PRE_DIRS = UNIX -else -PRE_DIRS = $(BLD_HOST_OS) -endif - -compileExtra: .updated - -.updated: $(FILES) - @touch .updated - -## Local variables: -## tab-width: 4 -## End: -## vim: tw=78 sw=4 ts=4 diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/README.TXT b/source4/lib/appweb/ejs-2.0/ejs/system/README.TXT deleted file mode 100644 index a24e0e299c..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/README.TXT +++ /dev/null @@ -1,63 +0,0 @@ -Embedded JavaScript System Model - - -- Need args, arg types and exceptions thrown -- Error classes - -class Global - class System - class environment - var - class GC - void function run() - function tune() - function getUsedMemory() // Should be properties - function getAllocatedMemory() // Should be properties - - var javascript - var null - var undefined - var true - var false - var Nan - var Infinity - - function random // Not implemented - function sleep // Not implemented - function exit - function yield // Not implemented - - Debug - isDebugMode - - Limits - isLimitsMode // Not implemented - stack // Not implemented - heap // Not implemented - flash // Not implemented - - Memory - getUsedMemory() // Should be properties - getAvailableMemory() // Should be properties - used - flash // Not implemented - - assert() - breakpoint() - dirname() - basename() - eval() - exit() - print() - println() - printVars() - sleep() - sort() - time() - typeof() - include() - trace() - printf() // Not implemented - sprintf() - - diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/.ignore b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/.ignore deleted file mode 100644 index fb5a29031e..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/.ignore +++ /dev/null @@ -1 +0,0 @@ -.updated diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/Makefile b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/Makefile deleted file mode 100755 index 424747052a..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# Makefile to build the EJS Object Model for WIN -# -# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. -# - -COMPILE := *.c -EXPORT_OBJECTS := yes -MAKE_IFLAGS := -I../.. -I../../../mpr - -include make.dep - -compileExtra: .updated - -.updated: $(FILES) - @touch .updated - -## Local variables: -## tab-width: 4 -## End: -## vim: tw=78 sw=4 ts=4 diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFile.c b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFile.c deleted file mode 100644 index 772303152e..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFile.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * @file ejsFile.c - * @brief File class for the EJ System Object Model - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/******************************************************************************/ -/* - * Default Constructor - */ - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -/* - * function open(); - */ - -static int openProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "File.open()\n"); - return 0; -} - -/******************************************************************************/ -/* - * function close(); - */ - -static int closeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "File.close()\n"); - return 0; -} - -/******************************************************************************/ -/* - * function read(); - */ - -static int readProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "File.read()\n"); - return 0; -} - -/******************************************************************************/ -/* - * function write(); - */ - -static int writeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "File.write()\n"); - return 0; -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineFileClass(Ejs *ep) -{ - EjsVar *fileClass; - - fileClass = ejsDefineClass(ep, "File", "Object", 0); - if (fileClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the methods - */ - ejsDefineCMethod(ep, fileClass, "open", openProc, 0); - ejsDefineCMethod(ep, fileClass, "close", closeProc, 0); - ejsDefineCMethod(ep, fileClass, "read", readProc, 0); - ejsDefineCMethod(ep, fileClass, "write", writeProc, 0); - - return ejsObjHasErrors(fileClass) ? MPR_ERR_CANT_INITIALIZE: 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFileSystem.c b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFileSystem.c deleted file mode 100755 index 7b39c16e4d..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsFileSystem.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - * @file ejsFileSystem.c - * @brief FileSystem class for the EJ System Object Model - * MOB -- this is almost the same as for Windows. Should common up. - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" -#include <dirent.h> - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -/* - * function void access(string path); - * MOB - API insufficient. Access for read or write? - */ - -static int accessProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: access(path)"); - return -1; - } - - rc = access(argv[0]->string, 04); - - ejsSetReturnValueToBoolean(ejs, (rc == 0) ? 1 : 0); - return 0; -} - -/******************************************************************************/ -/* - * function void mkdir(string path); - */ - -static int mkdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)"); - return -1; - } - - if (mprMakeDirPath(ejs, argv[0]->string) < 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant create directory"); - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * function void rmdir(string path); - */ - -static int rmdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)"); - return -1; - } - - rc = mprDeleteDir(ejs, argv[0]->string); - - if (rc < 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant remove directory"); - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * function void dirList(string path, [bool enumDirs]); - * MOB -- need pattern to match (what about "." and ".." and ".*" - */ - -static int dirListProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - DIR *dir; - struct dirent *dirent; - char path[MPR_MAX_FNAME]; - EjsVar *array, *vp; - uchar enumDirs; - - if (argc < 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: dirList(path)"); - return -1; - } - if (argc == 2) { - enumDirs = ejsVarToBoolean(argv[1]); - } else { - enumDirs = 0; - } - array = ejsCreateArray(ejs, 0); - ejsMakeObjPermanent(array, 1); - - /* - * First collect the files - */ - mprSprintf(path, sizeof(path), "%s/*.*", argv[0]->string); - - dir = opendir(path); - if (dir == 0) { - ejsError(ejs, EJS_ARG_ERROR, "Can't enumerate dirList(path)"); - return -1; - } - - while ((dirent = readdir(dir)) != 0) { - if (dirent->d_name[0] == '.') { - continue; - } - if (!enumDirs || (dirent->d_type & DT_DIR)) { - mprSprintf(path, sizeof(path), "%s/%s", argv[0]->string, - dirent->d_name); - vp = ejsCreateStringVar(ejs, path); - ejsAddArrayElt(ejs, array, vp, EJS_SHALLOW_COPY); - ejsFreeVar(ejs, vp); - } - } - - closedir(dir); - - ejsSetReturnValue(ejs, array); - ejsMakeObjPermanent(array, 0); - - /* - * Can free now as the return value holds the reference - */ - ejsFreeVar(ejs, array); - - return 0; -} - -/******************************************************************************/ -/* - * function void getFreeSpace(); - */ - -static int getFreeSpaceProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ -#if UNUSED - MprApp *app; - uint space; - - app = mprGetApp(ejs); - space = IFILEMGR_GetFreeSpace(app->fileMgr, 0); - ejsSetReturnValueToInteger(ejs, space); -#endif - - return 0; -} - -/******************************************************************************/ -/* - * function void writeFile(string path, var data); - */ - -static int writeFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprFile *file; - char *data, *buf; - int bytes, length, rc; - - if (argc != 2 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: writeFile(path, var)"); - return -1; - } - - if (ejsVarIsString(argv[1])) { - data = argv[1]->string; - length = argv[1]->length; - buf = 0; - } else { - buf = data = ejsVarToString(ejs, argv[1]); - length = strlen(data); - } - - /* - * Create fails if already present - */ - rc = mprDelete(ejs, argv[0]->string); - file = mprOpen(ejs, argv[0]->string, O_CREAT | O_WRONLY | O_BINARY, 0664); - if (file == 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[0]->string); - mprFree(buf); - return -1; - } - - rc = 0; - bytes = mprWrite(file, data, length); - if (bytes != length) { - ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string); - rc = -1; - } - - mprClose(file); - - mprFree(buf); - return rc; -} - -/******************************************************************************/ -/* - * function string readFile(string path); - */ - -static int readFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprApp *app; - MprFile *file; - MprBuf *buf; - char *data; - int bytes, rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: readFile(path)"); - return -1; - } - buf = mprCreateBuf(ejs, MPR_BUF_INCR, MPR_MAX_BUF); - if (buf == 0) { - ejsMemoryError(ejs); - return -1; - } - - data = mprAlloc(ejs, MPR_BUFSIZE); - if (buf == 0) { - mprFree(buf); - ejsMemoryError(ejs); - return -1; - } - - app = mprGetApp(ejs); - file = mprOpen(ejs, argv[0]->string, O_RDONLY, 0664); - if (file == 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string); - mprFree(buf); - return -1; - } - - rc = 0; - while ((bytes = mprRead(file, data, MPR_BUFSIZE)) > 0) { - if (mprPutBlockToBuf(buf, data, bytes) != bytes) { - ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string); - rc = -1; - break; - } - } - - ejsSetReturnValueToBinaryString(ejs, (uchar*) mprGetBufStart(buf), - mprGetBufLength(buf)); - - mprClose(file); - mprFree(data); - mprFree(buf); - - return rc; -} - -/******************************************************************************/ -/* - * function void remove(string path); - */ - -static int removeProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: remove(path)"); - return -1; - } - - rc = unlink(argv[0]->string); - if (rc < 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant remove file"); - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * function void rename(string from, string to); - */ - -static int renameProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: rename(old, new)"); - return -1; - } - - unlink(argv[1]->string); - rc = rename(argv[0]->string, argv[1]->string); - if (rc < 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant rename file"); - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * function void copy(string old, string new); - */ - -static int copyProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprFile *from, *to; - char *buf; - uint bytes; - int rc; - - if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: copy(old, new)"); - return -1; - } - - buf = mprAlloc(ejs, MPR_BUFSIZE); - if (buf == 0) { - ejsMemoryError(ejs); - return -1; - } - - from = mprOpen(ejs, argv[0]->string, O_RDONLY | O_BINARY, 0664); - if (from == 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string); - mprFree(buf); - return -1; - } - - to = mprOpen(ejs, argv[1]->string, O_CREAT | O_BINARY, 0664); - if (to == 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[1]->string); - mprClose(from); - mprFree(buf); - return -1; - } - - rc = 0; - while ((bytes = mprRead(from, buf, MPR_BUFSIZE)) > 0) { - if (mprWrite(to, buf, bytes) != bytes) { - ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string); - rc = -1; - break; - } - } - - mprClose(from); - mprClose(to); - mprFree(buf); - - return rc; -} - -/******************************************************************************/ -/* - * function FileInfo getFileInfo(string path); - * - * MOB -- should create a real class FileInfo - */ - -static int getFileInfoProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprFileInfo info; - EjsVar *fileInfo; - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: getFileInfo(path)"); - return -1; - } - - fileInfo = ejsCreateObjVar(ejs); - if (fileInfo == 0) { - ejsMemoryError(ejs); - return -1; - } - ejsMakeObjPermanent(fileInfo, 1); - - rc = mprGetFileInfo(ejs, argv[0]->string, &info); - if (rc < 0) { - ejsMakeObjPermanent(fileInfo, 0); - ejsFreeVar(ejs, fileInfo); - ejsError(ejs, EJS_IO_ERROR, "Cant get file info for %s", - argv[0]->string); - return -1; - } - - ejsSetPropertyToInteger(ejs, fileInfo, "created", info.ctime); - ejsSetPropertyToInteger(ejs, fileInfo, "length", info.size); - ejsSetPropertyToBoolean(ejs, fileInfo, "isDir", info.isDir); - - ejsSetReturnValue(ejs, fileInfo); - ejsMakeObjPermanent(fileInfo, 0); - - return 0; -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineFileSystemClass(Ejs *ejs) -{ - EjsVar *fileSystemClass; - - fileSystemClass = ejsDefineClass(ejs, "FileSystem", "Object", 0); - if (fileSystemClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the methods - */ - ejsDefineCMethod(ejs, fileSystemClass, "access", accessProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "mkdir", mkdirProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "rmdir", rmdirProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "dirList", dirListProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "writeFile", writeFileProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "readFile", readFileProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "remove", removeProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "rename", renameProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "copy", copyProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "getFileInfo", getFileInfoProc, 0); - - // MOB -- should be a property with accessor - ejsDefineCMethod(ejs, fileSystemClass, "getFreeSpace", getFreeSpaceProc, 0); - - return ejsObjHasErrors(fileSystemClass) ? MPR_ERR_CANT_INITIALIZE: 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsHTTP.c b/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsHTTP.c deleted file mode 100755 index 25821f6960..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/UNIX/ejsHTTP.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * @file ejsHTTP.c - * @brief HTTP class for the EJ System Object Model - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -#if UNUSED -/*********************************** Defines **********************************/ - -#define EJS_WEB_PROPERTY "-web" -#define EJS_HTTP_PROPERTY "-http" - -#define EJS_HTTP_DISPOSED 550 - -/* - * Control structure for one HTTP request structure - */ -typedef struct HTTPControl { - Ejs *ejs; - IWebResp *webResp; - AEECallback *callback; - MprBuf *buf; - EjsVar *thisObj; - char *url; - MprTime requestStarted; - uint timeout; -} HTTPControl; - -/****************************** Forward Declarations **************************/ - -static void cleanup(HTTPControl *hp); -static int createWeb(Ejs *ejs, EjsVar *thisObj); -static void brewCallback(HTTPControl *hp); -static int httpDestructor(Ejs *ejs, EjsVar *vp); -static void httpCallback(HTTPControl *hp, int responseCode); -static int setCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv); - -/******************************************************************************/ -/* - * Constructor - */ - -int ejsHTTPConstructor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 0 && argc != 2) { - ejsError(ejs, EJS_ARG_ERROR, - "Bad usage: HTTP([obj = this, method = onComplete]);"); - return -1; - } - - if (createWeb(ejs, thisObj) < 0) { - return -1; - } - - setCallback(ejs, thisObj, argc, argv); - return 0; -} - -/******************************************************************************/ - -static int createWeb(Ejs *ejs, EjsVar *thisObj) -{ - MprApp *app; - void *web; - - app = mprGetApp(ejs); - - /* - * Create one instance of IWeb for the entire application. Do it here - * so only widgets that require HTTP incurr the overhead. - */ - web = mprGetKeyValue(ejs, "bpWeb"); - if (web == 0) { - if (ISHELL_CreateInstance(app->shell, AEECLSID_WEB, &web) != SUCCESS) { - ejsError(ejs, EJS_IO_ERROR, "Can't create IWEB"); - return -1; - } - } - mprSetKeyValue(ejs, "bpWeb", web); - return 0; -} - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -/* - * function setCallback(obj, methodString); - */ - -static int setCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc >= 1) { - ejsSetProperty(ejs, thisObj, "obj", argv[0]); - } else { - ejsSetProperty(ejs, thisObj, "obj", thisObj); - } - - if (argc >= 2) { - ejsSetProperty(ejs, thisObj, "method", argv[1]); - } else { - ejsSetPropertyToString(ejs, thisObj, "method", "onComplete"); - } - - return 0; -} - -/******************************************************************************/ -/* - * function fetch(); - */ - -static int fetchProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - HTTPControl *hp; - EjsProperty *pp; - MprApp *app; - IWeb *web; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: fetch(url)"); - return -1; - } - - app = mprGetApp(ejs); - web = (IWeb*) mprGetKeyValue(ejs, "bpWeb"); - - /* - * Web options - * - * WEBOPT_USERAGENT (char*) sets user agent - * WEBOPT_HANDLERDATA (void*) - * WEBOPT_CONNECTTIMEOUT (uint) msec - * WEBOPT_CONTENTLENGTH (long) - * WEBOPT_IDLECONNTIMEOUT (int) - * WEBOPT_ACTIVEXACTIONST (uint) Number of active requests - * - * WEBREQUEST_REDIRECT redirect transparently - * - */ - - hp = mprAllocType(ejs, HTTPControl); - if (hp == 0) { - ejsMemoryError(ejs); - return -1; - } - - hp->ejs = ejs; - hp->buf = mprCreateBuf(hp, MPR_BUF_INCR, MPR_MAX_BUF); - if (hp->buf == 0) { - mprFree(hp); - ejsMemoryError(ejs); - return -1; - } - - /* - * We copy thisObj because we need to preserve both the var and the object. - * We pass the var to brewCallback and so it must persist. The call to - * ejsMakeObjPermanent will stop the GC from collecting the object. - */ - hp->thisObj = ejsDupVar(ejs, thisObj, EJS_SHALLOW_COPY); - ejsSetVarName(ejs, hp->thisObj, "internalHttp"); - - /* - * Must keep a reference to the http object - */ - ejsMakeObjPermanent(hp->thisObj, 1); - - /* - * Make a property so we can access the HTTPControl structure from other - * methods. - */ - pp = ejsSetPropertyToPtr(ejs, thisObj, EJS_HTTP_PROPERTY, hp, 0); - ejsMakePropertyEnumerable(pp, 0); - ejsSetObjDestructor(ejs, hp->thisObj, httpDestructor); - - hp->url = mprStrdup(hp, argv[0]->string); - - hp->timeout = ejsGetPropertyAsInteger(ejs, thisObj, "timeout"); - mprGetTime(hp, &hp->requestStarted); - - hp->callback = mprAllocTypeZeroed(hp, AEECallback); - CALLBACK_Init(hp->callback, brewCallback, hp); - - hp->webResp = 0; - IWEB_GetResponse(web, - (web, &hp->webResp, hp->callback, hp->url, - WEBOPT_HANDLERDATA, hp, - WEBOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)", - WEBOPT_CONNECTTIMEOUT, hp->timeout, - WEBOPT_COPYOPTS, TRUE, - WEBOPT_CONTENTLENGTH, 0, - WEBOPT_END)); - - ejsSetPropertyToString(ejs, thisObj, "status", "active"); - - return 0; -} - -/******************************************************************************/ -/* - * Called whenver the http object is deleted. - */ - -static int httpDestructor(Ejs *ejs, EjsVar *thisObj) -{ - HTTPControl *hp; - - /* - * If the httpCallback has run, then this property will not exist - */ - hp = ejsGetPropertyAsPtr(ejs, thisObj, EJS_HTTP_PROPERTY); - - if (hp) { - cleanup(hp); - } - - return 0; -} - -/******************************************************************************/ -/* - * Stop the request immediately without calling the callback - */ - -static int stopProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - HTTPControl *hp; - - hp = ejsGetPropertyAsPtr(ejs, thisObj, EJS_HTTP_PROPERTY); - - if (hp) { - cleanup(hp); - } - - return 0; -} - -/******************************************************************************/ -/* - * Brew HTTP callback. Invoked for any return data. - */ - -static void brewCallback(HTTPControl *hp) -{ - Ejs *ejs; - EjsVar *thisObj; - ISource *source; - WebRespInfo *info; - char data[MPR_BUF_INCR]; - int bytes; - - mprAssert(hp); - mprAssert(hp->webResp); - - info = IWEBRESP_GetInfo(hp->webResp); - - if (info == 0) { - mprAssert(info); - /* should not happen */ - return; - } - - ejs = hp->ejs; - thisObj = hp->thisObj; - - if (! WEB_ERROR_SUCCEEDED(info->nCode)) { - ejsSetPropertyToString(ejs, thisObj, "status", "error"); - httpCallback(hp, info->nCode); - return; - } - - if (hp->timeout) { - if (mprGetTimeRemaining(hp, hp->requestStarted, hp->timeout) <= 0) { - ejsSetPropertyToString(ejs, thisObj, "status", "timeout"); - httpCallback(hp, 504); - return; - } - } - - /* - * Normal success - */ - source = info->pisMessage; - mprAssert(source); - - bytes = ISOURCE_Read(source, data, sizeof(data)); - - switch (bytes) { - case ISOURCE_WAIT: // No data yet - ISOURCE_Readable(source, hp->callback); - break; - - case ISOURCE_ERROR: - ejsSetPropertyToString(ejs, thisObj, "status", "error"); - httpCallback(hp, info->nCode); - break; - - case ISOURCE_END: - mprAddNullToBuf(hp->buf); - ejsSetPropertyToString(ejs, thisObj, "status", "complete"); - httpCallback(hp, info->nCode); - break; - - default: - if (bytes > 0) { - if (mprPutBlockToBuf(hp->buf, data, bytes) != bytes) { - ejsSetPropertyToString(ejs, thisObj, "status", "partialData"); - httpCallback(hp, 500); - } - } - ISOURCE_Readable(source, hp->callback); - break; - } -} - -/******************************************************************************/ -/* - * Invoke the HTTP completion method - */ - -static void httpCallback(HTTPControl *hp, int responseCode) -{ - Ejs *ejs; - EjsVar *thisObj, *callbackObj; - MprArray *args; - char *msg; - const char *callbackMethod; - - mprAssert(hp); - mprAssert(hp->webResp); - - thisObj = hp->thisObj; - ejs = hp->ejs; - - ejsSetPropertyToInteger(ejs, thisObj, "responseCode", responseCode); - if (mprGetBufLength(hp->buf) > 0) { - ejsSetPropertyToBinaryString(ejs, thisObj, "responseData", - mprGetBufStart(hp->buf), mprGetBufLength(hp->buf)); - } - - callbackObj = ejsGetPropertyAsVar(ejs, thisObj, "obj"); - callbackMethod = ejsGetPropertyAsString(ejs, thisObj, "method"); - - if (callbackObj != 0 && callbackMethod != 0) { - - args = mprCreateItemArray(ejs, EJS_INC_ARGS, EJS_MAX_ARGS); - mprAddItem(args, ejsDupVar(ejs, hp->thisObj, EJS_SHALLOW_COPY)); - - if (ejsRunMethod(ejs, callbackObj, callbackMethod, args) < 0) { - msg = ejsGetErrorMsg(ejs); - mprError(ejs, MPR_LOC, "HTTP callback failed. Details: %s", msg); - } - ejsFreeMethodArgs(ejs, args); - - } else if (ejsRunMethod(ejs, thisObj, "onComplete", 0) < 0) { - msg = ejsGetErrorMsg(ejs); - mprError(ejs, MPR_LOC, "HTTP onComplete failed. Details: %s", msg); - } - - cleanup(hp); -} - -/******************************************************************************/ -/* - * Cleanup - */ - -static void cleanup(HTTPControl *hp) -{ - Ejs *ejs; - MprApp *app; - int rc; - - mprAssert(hp); - mprAssert(hp->webResp); - - ejs = hp->ejs; - - if (hp->webResp) { - rc = IWEBRESP_Release(hp->webResp); - // mprAssert(rc == 0); - hp->webResp = 0; - } - - if (hp->callback) { - CALLBACK_Cancel(hp->callback); - mprFree(hp->callback); - hp->callback = 0; - } - - /* - * Once the property is deleted, then if the destructor runs, it will - * notice that the EJS_HTTP_PROPERTY is undefined. - */ - ejsDeleteProperty(ejs, hp->thisObj, EJS_HTTP_PROPERTY); - - /* - * Allow garbage collection to work on thisObj - */ - ejsMakeObjPermanent(hp->thisObj, 0); - ejsFreeVar(ejs, hp->thisObj); - - mprFree(hp->buf); - mprFree(hp->url); - - mprFree(hp); - - app = mprGetApp(ejs); - - - ISHELL_SendEvent(app->shell, (AEECLSID) app->classId, EVT_USER, 0, 0); -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineHTTPClass(Ejs *ejs) -{ - EjsVar *httpClass; - - httpClass = - ejsDefineClass(ejs, "HTTP", "Object", ejsHTTPConstructor); - if (httpClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the methods - */ - ejsDefineCMethod(ejs, httpClass, "fetch", fetchProc, 0); - ejsDefineCMethod(ejs, httpClass, "stop", stopProc, 0); - ejsDefineCMethod(ejs, httpClass, "setCallback", setCallback, 0); - -#if FUTURE - ejsDefineCMethod(ejs, httpClass, "put", put, 0); - ejsDefineCMethod(ejs, httpClass, "upload", upload, 0); - ejsDefineCMethod(ejs, httpClass, "addUploadFile", addUploadFile, 0); - ejsDefineCMethod(ejs, httpClass, "addPostData", addPostData, 0); - ejsDefineCMethod(ejs, httpClass, "setUserPassword", setUserPassword, 0); - ejsDefineCMethod(ejs, httpClass, "addCookie", addCookie, 0); -#endif - - /* - * Define properties - */ - ejsSetPropertyToString(ejs, httpClass, "status", "inactive"); - - /* This default should come from player.xml */ - - ejsSetPropertyToInteger(ejs, httpClass, "timeout", 30 * 1000); - ejsSetPropertyToInteger(ejs, httpClass, "responseCode", 0); - - return ejsObjHasErrors(httpClass) ? MPR_ERR_CANT_INITIALIZE: 0; -} - -/******************************************************************************/ - -void ejsTermHTTPClass(Ejs *ejs) -{ - IWeb *web; - int rc; - - web = (IWeb*) mprGetKeyValue(ejs, "bpWeb"); - if (web) { - rc = IWEB_Release(web); - mprAssert(rc == 0); - } -} - -#endif -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/.ignore b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/.ignore deleted file mode 100644 index fb5a29031e..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/.ignore +++ /dev/null @@ -1 +0,0 @@ -.updated diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/Makefile b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/Makefile deleted file mode 100755 index 424747052a..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# Makefile to build the EJS Object Model for WIN -# -# Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. -# - -COMPILE := *.c -EXPORT_OBJECTS := yes -MAKE_IFLAGS := -I../.. -I../../../mpr - -include make.dep - -compileExtra: .updated - -.updated: $(FILES) - @touch .updated - -## Local variables: -## tab-width: 4 -## End: -## vim: tw=78 sw=4 ts=4 diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFile.c b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFile.c deleted file mode 100644 index 24c521891e..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFile.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * @file ejsFile.c - * @brief File class for the EJScript System Object Model - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/******************************************************************************/ -/* - * Default Constructor - */ - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -/* - * function open(); - */ - -static int openProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "File.open()\n"); - return 0; -} - -/******************************************************************************/ -/* - * function close(); - */ - -static int closeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "File.close()\n"); - return 0; -} - -/******************************************************************************/ -/* - * function read(); - */ - -static int readProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "File.read()\n"); - return 0; -} - -/******************************************************************************/ -/* - * function write(); - */ - -static int writeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "File.write()\n"); - return 0; -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineFileClass(Ejs *ep) -{ - EjsVar *fileClass; - - fileClass = ejsDefineClass(ep, "File", "Object", 0); - if (fileClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the methods - */ - ejsDefineCMethod(ep, fileClass, "open", openProc, 0); - ejsDefineCMethod(ep, fileClass, "close", closeProc, 0); - ejsDefineCMethod(ep, fileClass, "read", readProc, 0); - ejsDefineCMethod(ep, fileClass, "write", writeProc, 0); - - return ejsObjHasErrors(fileClass) ? MPR_ERR_CANT_INITIALIZE: 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFileSystem.c b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFileSystem.c deleted file mode 100755 index 66c3b84870..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsFileSystem.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * @file ejsFileSystem.c - * @brief FileSystem class for the EJ System Object Model - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/******************************************************************************/ -/* - * Default Constructor - */ - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -/* - * function void access(string path); - * MOB - API insufficient. Access for read or write? - */ - -static int accessProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: access(path)"); - return -1; - } - - rc = access(argv[0]->string, 04); - - ejsSetReturnValueToBoolean(ejs, (rc == 0) ? 1 : 0); - return 0; -} - -/******************************************************************************/ -/* - * function void mkdir(string path); - */ - -static int mkdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)"); - return -1; - } - - if (mprMakeDirPath(ejs, argv[0]->string) < 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant create directory"); - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * function void rmdir(string path); - */ - -static int rmdirProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: mkdir(path)"); - return -1; - } - - rc = mprDeleteDir(ejs, argv[0]->string); - - if (rc < 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant remove directory"); - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * function void dirList(string path, [bool enumDirs]); - * MOB -- need pattern to match (what about "." and ".." and ".*" - */ - -static int dirListProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - WIN32_FIND_DATA findData; - HANDLE h; - char path[MPR_MAX_FNAME]; - EjsVar *array, *vp; - uchar enumDirs; - - if (argc < 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: dirList(path)"); - return -1; - } - if (argc == 2) { - enumDirs = ejsVarToBoolean(argv[1]); - } else { - enumDirs = 0; - } - array = ejsCreateArray(ejs, 0); - ejsMakeObjPermanent(array, 1); - - /* - * First collect the files - */ - mprSprintf(path, sizeof(path), "%s/*.*", argv[0]->string); - h = FindFirstFile(path, &findData); - if (h == INVALID_HANDLE_VALUE) { - ejsError(ejs, EJS_ARG_ERROR, "Can't enumerate dirList(path)"); - return -1; - } - - do { - if (findData.cFileName[0] == '.') { - continue; - } - if (!enumDirs || - (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - mprSprintf(path, sizeof(path), "%s/%s", argv[0]->string, - findData.cFileName); - vp = ejsCreateStringVar(ejs, path); - ejsAddArrayElt(ejs, array, vp, EJS_SHALLOW_COPY); - ejsFreeVar(ejs, vp); - } - } while (FindNextFile(h, &findData) != 0); - - FindClose(h); - - ejsSetReturnValue(ejs, array); - ejsMakeObjPermanent(array, 0); - - /* - * Can free now as the return value holds the reference - */ - ejsFreeVar(ejs, array); - - return 0; -} - -/******************************************************************************/ -/* - * function void getFreeSpace(); - */ - -static int getFreeSpaceProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ -#if UNUSED - MprApp *app; - uint space; - - app = mprGetApp(ejs); - space = IFILEMGR_GetFreeSpace(app->fileMgr, 0); - ejsSetReturnValueToInteger(ejs, space); -#endif - - return 0; -} - -/******************************************************************************/ -/* - * function void writeFile(string path, var data); - */ - -static int writeFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprFile *file; - char *data, *buf; - int bytes, length, rc; - - if (argc != 2 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: writeFile(path, var)"); - return -1; - } - - if (ejsVarIsString(argv[1])) { - data = argv[1]->string; - length = argv[1]->length; - buf = 0; - } else { - buf = data = ejsVarToString(ejs, argv[1]); - length = strlen(data); - } - - /* - * Create fails if already present - */ - rc = mprDelete(ejs, argv[0]->string); - file = mprOpen(ejs, argv[0]->string, O_CREAT | O_WRONLY | O_BINARY, 0664); - if (file == 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[0]->string); - mprFree(buf); - return -1; - } - - rc = 0; - bytes = mprWrite(file, data, length); - if (bytes != length) { - ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string); - rc = -1; - } - - mprClose(file); - - mprFree(buf); - return rc; -} - -/******************************************************************************/ -/* - * function string readFile(string path); - */ - -static int readFileProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprApp *app; - MprFile *file; - MprBuf *buf; - char *data; - int bytes, rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: readFile(path)"); - return -1; - } - buf = mprCreateBuf(ejs, MPR_BUF_INCR, MPR_MAX_BUF); - if (buf == 0) { - ejsMemoryError(ejs); - return -1; - } - - data = mprAlloc(ejs, MPR_BUFSIZE); - if (buf == 0) { - mprFree(buf); - ejsMemoryError(ejs); - return -1; - } - - app = mprGetApp(ejs); - file = mprOpen(ejs, argv[0]->string, O_RDONLY, 0664); - if (file == 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string); - mprFree(buf); - return -1; - } - - rc = 0; - while ((bytes = mprRead(file, data, MPR_BUFSIZE)) > 0) { - if (mprPutBlockToBuf(buf, data, bytes) != bytes) { - ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string); - rc = -1; - break; - } - } - - ejsSetReturnValueToBinaryString(ejs, mprGetBufStart(buf), - mprGetBufLength(buf)); - - mprClose(file); - mprFree(data); - mprFree(buf); - - return rc; -} - -/******************************************************************************/ -/* - * function void remove(string path); - */ - -static int removeProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: remove(path)"); - return -1; - } - - rc = unlink(argv[0]->string); - if (rc < 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant remove file"); - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * function void rename(string from, string to); - */ - -static int renameProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int rc; - - if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: rename(old, new)"); - return -1; - } - - unlink(argv[1]->string); - rc = rename(argv[0]->string, argv[1]->string); - if (rc < 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant rename file"); - return -1; - } - return 0; -} - -/******************************************************************************/ -/* - * function void copy(string old, string new); - */ - -static int copyProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprFile *from, *to; - char *buf; - int bytes, rc; - - if (argc != 2 || !ejsVarIsString(argv[0]) || !ejsVarIsString(argv[1])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: copy(old, new)"); - return -1; - } - - buf = mprAlloc(ejs, MPR_BUFSIZE); - if (buf == 0) { - ejsMemoryError(ejs); - return -1; - } - - from = mprOpen(ejs, argv[0]->string, O_RDONLY | O_BINARY, 0664); - if (from == 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant open %s", argv[0]->string); - mprFree(buf); - return -1; - } - - to = mprOpen(ejs, argv[1]->string, O_CREAT | O_BINARY, 0664); - if (to == 0) { - ejsError(ejs, EJS_IO_ERROR, "Cant create %s", argv[1]->string); - mprClose(from); - mprFree(buf); - return -1; - } - - rc = 0; - while ((bytes = mprRead(from, buf, MPR_BUFSIZE)) > 0) { - if (mprWrite(to, buf, bytes) != bytes) { - ejsError(ejs, EJS_IO_ERROR, "Write error to %s", argv[1]->string); - rc = -1; - break; - } - } - - mprClose(from); - mprClose(to); - mprFree(buf); - - return rc; -} - -/******************************************************************************/ -/* - * function FileInfo getFileInfo(string path); - * - * MOB -- should create a real class FileInfo - */ - -static int getFileInfoProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - MprFileInfo info; - EjsVar *fileInfo; - int rc; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: getFileInfo(path)"); - return -1; - } - - fileInfo = ejsCreateObjVar(ejs); - if (fileInfo == 0) { - ejsMemoryError(ejs); - return -1; - } - ejsMakeObjPermanent(fileInfo, 1); - - rc = mprGetFileInfo(ejs, argv[0]->string, &info); - if (rc < 0) { - ejsMakeObjPermanent(fileInfo, 0); - ejsFreeVar(ejs, fileInfo); - ejsError(ejs, EJS_IO_ERROR, "Cant get file info for %s", - argv[0]->string); - return -1; - } - - ejsSetPropertyToInteger(ejs, fileInfo, "created", info.ctime); - ejsSetPropertyToInteger(ejs, fileInfo, "length", info.size); - ejsSetPropertyToBoolean(ejs, fileInfo, "isDir", info.isDir); - - ejsSetReturnValue(ejs, fileInfo); - ejsMakeObjPermanent(fileInfo, 0); - - return 0; -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineFileSystemClass(Ejs *ejs) -{ - EjsVar *fileSystemClass; - - fileSystemClass = ejsDefineClass(ejs, "FileSystem", "Object", 0); - if (fileSystemClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the methods - */ - ejsDefineCMethod(ejs, fileSystemClass, "access", accessProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "mkdir", mkdirProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "rmdir", rmdirProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "dirList", dirListProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "writeFile", writeFileProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "readFile", readFileProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "remove", removeProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "rename", renameProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "copy", copyProc, 0); - ejsDefineCMethod(ejs, fileSystemClass, "getFileInfo", getFileInfoProc, 0); - - // MOB -- should be a property with accessor - ejsDefineCMethod(ejs, fileSystemClass, "getFreeSpace", getFreeSpaceProc, 0); - - return ejsObjHasErrors(fileSystemClass) ? MPR_ERR_CANT_INITIALIZE: 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsHTTP.c b/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsHTTP.c deleted file mode 100755 index 25821f6960..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/WIN/ejsHTTP.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * @file ejsHTTP.c - * @brief HTTP class for the EJ System Object Model - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -#if UNUSED -/*********************************** Defines **********************************/ - -#define EJS_WEB_PROPERTY "-web" -#define EJS_HTTP_PROPERTY "-http" - -#define EJS_HTTP_DISPOSED 550 - -/* - * Control structure for one HTTP request structure - */ -typedef struct HTTPControl { - Ejs *ejs; - IWebResp *webResp; - AEECallback *callback; - MprBuf *buf; - EjsVar *thisObj; - char *url; - MprTime requestStarted; - uint timeout; -} HTTPControl; - -/****************************** Forward Declarations **************************/ - -static void cleanup(HTTPControl *hp); -static int createWeb(Ejs *ejs, EjsVar *thisObj); -static void brewCallback(HTTPControl *hp); -static int httpDestructor(Ejs *ejs, EjsVar *vp); -static void httpCallback(HTTPControl *hp, int responseCode); -static int setCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv); - -/******************************************************************************/ -/* - * Constructor - */ - -int ejsHTTPConstructor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 0 && argc != 2) { - ejsError(ejs, EJS_ARG_ERROR, - "Bad usage: HTTP([obj = this, method = onComplete]);"); - return -1; - } - - if (createWeb(ejs, thisObj) < 0) { - return -1; - } - - setCallback(ejs, thisObj, argc, argv); - return 0; -} - -/******************************************************************************/ - -static int createWeb(Ejs *ejs, EjsVar *thisObj) -{ - MprApp *app; - void *web; - - app = mprGetApp(ejs); - - /* - * Create one instance of IWeb for the entire application. Do it here - * so only widgets that require HTTP incurr the overhead. - */ - web = mprGetKeyValue(ejs, "bpWeb"); - if (web == 0) { - if (ISHELL_CreateInstance(app->shell, AEECLSID_WEB, &web) != SUCCESS) { - ejsError(ejs, EJS_IO_ERROR, "Can't create IWEB"); - return -1; - } - } - mprSetKeyValue(ejs, "bpWeb", web); - return 0; -} - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -/* - * function setCallback(obj, methodString); - */ - -static int setCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc >= 1) { - ejsSetProperty(ejs, thisObj, "obj", argv[0]); - } else { - ejsSetProperty(ejs, thisObj, "obj", thisObj); - } - - if (argc >= 2) { - ejsSetProperty(ejs, thisObj, "method", argv[1]); - } else { - ejsSetPropertyToString(ejs, thisObj, "method", "onComplete"); - } - - return 0; -} - -/******************************************************************************/ -/* - * function fetch(); - */ - -static int fetchProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - HTTPControl *hp; - EjsProperty *pp; - MprApp *app; - IWeb *web; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsError(ejs, EJS_ARG_ERROR, "Bad usage: fetch(url)"); - return -1; - } - - app = mprGetApp(ejs); - web = (IWeb*) mprGetKeyValue(ejs, "bpWeb"); - - /* - * Web options - * - * WEBOPT_USERAGENT (char*) sets user agent - * WEBOPT_HANDLERDATA (void*) - * WEBOPT_CONNECTTIMEOUT (uint) msec - * WEBOPT_CONTENTLENGTH (long) - * WEBOPT_IDLECONNTIMEOUT (int) - * WEBOPT_ACTIVEXACTIONST (uint) Number of active requests - * - * WEBREQUEST_REDIRECT redirect transparently - * - */ - - hp = mprAllocType(ejs, HTTPControl); - if (hp == 0) { - ejsMemoryError(ejs); - return -1; - } - - hp->ejs = ejs; - hp->buf = mprCreateBuf(hp, MPR_BUF_INCR, MPR_MAX_BUF); - if (hp->buf == 0) { - mprFree(hp); - ejsMemoryError(ejs); - return -1; - } - - /* - * We copy thisObj because we need to preserve both the var and the object. - * We pass the var to brewCallback and so it must persist. The call to - * ejsMakeObjPermanent will stop the GC from collecting the object. - */ - hp->thisObj = ejsDupVar(ejs, thisObj, EJS_SHALLOW_COPY); - ejsSetVarName(ejs, hp->thisObj, "internalHttp"); - - /* - * Must keep a reference to the http object - */ - ejsMakeObjPermanent(hp->thisObj, 1); - - /* - * Make a property so we can access the HTTPControl structure from other - * methods. - */ - pp = ejsSetPropertyToPtr(ejs, thisObj, EJS_HTTP_PROPERTY, hp, 0); - ejsMakePropertyEnumerable(pp, 0); - ejsSetObjDestructor(ejs, hp->thisObj, httpDestructor); - - hp->url = mprStrdup(hp, argv[0]->string); - - hp->timeout = ejsGetPropertyAsInteger(ejs, thisObj, "timeout"); - mprGetTime(hp, &hp->requestStarted); - - hp->callback = mprAllocTypeZeroed(hp, AEECallback); - CALLBACK_Init(hp->callback, brewCallback, hp); - - hp->webResp = 0; - IWEB_GetResponse(web, - (web, &hp->webResp, hp->callback, hp->url, - WEBOPT_HANDLERDATA, hp, - WEBOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)", - WEBOPT_CONNECTTIMEOUT, hp->timeout, - WEBOPT_COPYOPTS, TRUE, - WEBOPT_CONTENTLENGTH, 0, - WEBOPT_END)); - - ejsSetPropertyToString(ejs, thisObj, "status", "active"); - - return 0; -} - -/******************************************************************************/ -/* - * Called whenver the http object is deleted. - */ - -static int httpDestructor(Ejs *ejs, EjsVar *thisObj) -{ - HTTPControl *hp; - - /* - * If the httpCallback has run, then this property will not exist - */ - hp = ejsGetPropertyAsPtr(ejs, thisObj, EJS_HTTP_PROPERTY); - - if (hp) { - cleanup(hp); - } - - return 0; -} - -/******************************************************************************/ -/* - * Stop the request immediately without calling the callback - */ - -static int stopProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - HTTPControl *hp; - - hp = ejsGetPropertyAsPtr(ejs, thisObj, EJS_HTTP_PROPERTY); - - if (hp) { - cleanup(hp); - } - - return 0; -} - -/******************************************************************************/ -/* - * Brew HTTP callback. Invoked for any return data. - */ - -static void brewCallback(HTTPControl *hp) -{ - Ejs *ejs; - EjsVar *thisObj; - ISource *source; - WebRespInfo *info; - char data[MPR_BUF_INCR]; - int bytes; - - mprAssert(hp); - mprAssert(hp->webResp); - - info = IWEBRESP_GetInfo(hp->webResp); - - if (info == 0) { - mprAssert(info); - /* should not happen */ - return; - } - - ejs = hp->ejs; - thisObj = hp->thisObj; - - if (! WEB_ERROR_SUCCEEDED(info->nCode)) { - ejsSetPropertyToString(ejs, thisObj, "status", "error"); - httpCallback(hp, info->nCode); - return; - } - - if (hp->timeout) { - if (mprGetTimeRemaining(hp, hp->requestStarted, hp->timeout) <= 0) { - ejsSetPropertyToString(ejs, thisObj, "status", "timeout"); - httpCallback(hp, 504); - return; - } - } - - /* - * Normal success - */ - source = info->pisMessage; - mprAssert(source); - - bytes = ISOURCE_Read(source, data, sizeof(data)); - - switch (bytes) { - case ISOURCE_WAIT: // No data yet - ISOURCE_Readable(source, hp->callback); - break; - - case ISOURCE_ERROR: - ejsSetPropertyToString(ejs, thisObj, "status", "error"); - httpCallback(hp, info->nCode); - break; - - case ISOURCE_END: - mprAddNullToBuf(hp->buf); - ejsSetPropertyToString(ejs, thisObj, "status", "complete"); - httpCallback(hp, info->nCode); - break; - - default: - if (bytes > 0) { - if (mprPutBlockToBuf(hp->buf, data, bytes) != bytes) { - ejsSetPropertyToString(ejs, thisObj, "status", "partialData"); - httpCallback(hp, 500); - } - } - ISOURCE_Readable(source, hp->callback); - break; - } -} - -/******************************************************************************/ -/* - * Invoke the HTTP completion method - */ - -static void httpCallback(HTTPControl *hp, int responseCode) -{ - Ejs *ejs; - EjsVar *thisObj, *callbackObj; - MprArray *args; - char *msg; - const char *callbackMethod; - - mprAssert(hp); - mprAssert(hp->webResp); - - thisObj = hp->thisObj; - ejs = hp->ejs; - - ejsSetPropertyToInteger(ejs, thisObj, "responseCode", responseCode); - if (mprGetBufLength(hp->buf) > 0) { - ejsSetPropertyToBinaryString(ejs, thisObj, "responseData", - mprGetBufStart(hp->buf), mprGetBufLength(hp->buf)); - } - - callbackObj = ejsGetPropertyAsVar(ejs, thisObj, "obj"); - callbackMethod = ejsGetPropertyAsString(ejs, thisObj, "method"); - - if (callbackObj != 0 && callbackMethod != 0) { - - args = mprCreateItemArray(ejs, EJS_INC_ARGS, EJS_MAX_ARGS); - mprAddItem(args, ejsDupVar(ejs, hp->thisObj, EJS_SHALLOW_COPY)); - - if (ejsRunMethod(ejs, callbackObj, callbackMethod, args) < 0) { - msg = ejsGetErrorMsg(ejs); - mprError(ejs, MPR_LOC, "HTTP callback failed. Details: %s", msg); - } - ejsFreeMethodArgs(ejs, args); - - } else if (ejsRunMethod(ejs, thisObj, "onComplete", 0) < 0) { - msg = ejsGetErrorMsg(ejs); - mprError(ejs, MPR_LOC, "HTTP onComplete failed. Details: %s", msg); - } - - cleanup(hp); -} - -/******************************************************************************/ -/* - * Cleanup - */ - -static void cleanup(HTTPControl *hp) -{ - Ejs *ejs; - MprApp *app; - int rc; - - mprAssert(hp); - mprAssert(hp->webResp); - - ejs = hp->ejs; - - if (hp->webResp) { - rc = IWEBRESP_Release(hp->webResp); - // mprAssert(rc == 0); - hp->webResp = 0; - } - - if (hp->callback) { - CALLBACK_Cancel(hp->callback); - mprFree(hp->callback); - hp->callback = 0; - } - - /* - * Once the property is deleted, then if the destructor runs, it will - * notice that the EJS_HTTP_PROPERTY is undefined. - */ - ejsDeleteProperty(ejs, hp->thisObj, EJS_HTTP_PROPERTY); - - /* - * Allow garbage collection to work on thisObj - */ - ejsMakeObjPermanent(hp->thisObj, 0); - ejsFreeVar(ejs, hp->thisObj); - - mprFree(hp->buf); - mprFree(hp->url); - - mprFree(hp); - - app = mprGetApp(ejs); - - - ISHELL_SendEvent(app->shell, (AEECLSID) app->classId, EVT_USER, 0, 0); -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineHTTPClass(Ejs *ejs) -{ - EjsVar *httpClass; - - httpClass = - ejsDefineClass(ejs, "HTTP", "Object", ejsHTTPConstructor); - if (httpClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the methods - */ - ejsDefineCMethod(ejs, httpClass, "fetch", fetchProc, 0); - ejsDefineCMethod(ejs, httpClass, "stop", stopProc, 0); - ejsDefineCMethod(ejs, httpClass, "setCallback", setCallback, 0); - -#if FUTURE - ejsDefineCMethod(ejs, httpClass, "put", put, 0); - ejsDefineCMethod(ejs, httpClass, "upload", upload, 0); - ejsDefineCMethod(ejs, httpClass, "addUploadFile", addUploadFile, 0); - ejsDefineCMethod(ejs, httpClass, "addPostData", addPostData, 0); - ejsDefineCMethod(ejs, httpClass, "setUserPassword", setUserPassword, 0); - ejsDefineCMethod(ejs, httpClass, "addCookie", addCookie, 0); -#endif - - /* - * Define properties - */ - ejsSetPropertyToString(ejs, httpClass, "status", "inactive"); - - /* This default should come from player.xml */ - - ejsSetPropertyToInteger(ejs, httpClass, "timeout", 30 * 1000); - ejsSetPropertyToInteger(ejs, httpClass, "responseCode", 0); - - return ejsObjHasErrors(httpClass) ? MPR_ERR_CANT_INITIALIZE: 0; -} - -/******************************************************************************/ - -void ejsTermHTTPClass(Ejs *ejs) -{ - IWeb *web; - int rc; - - web = (IWeb*) mprGetKeyValue(ejs, "bpWeb"); - if (web) { - rc = IWEB_Release(web); - mprAssert(rc == 0); - } -} - -#endif -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGC.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsGC.c deleted file mode 100644 index 411975f80e..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGC.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * @file ejsGC.c - * @brief Garbage collector class for the EJS Object Model - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -#if (WIN || BREW_SIMULATOR) && BLD_DEBUG - -static int checkProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - _CrtCheckMemory(); - return 0; -} - -#endif -/******************************************************************************/ - -static int debugProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1) { - ejsError(ep, EJS_ARG_ERROR, "Bad args: debug(debugLevel)"); - return -1; - } - - ejsSetGCDebugLevel(ep, ejsVarToInteger(argv[0])); - return 0; -} - -/******************************************************************************/ -/* - * Print stats and dump objects - */ - -static int printStatsProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - bool leakStats; - - if (argc > 1) { - leakStats = ejsVarToInteger(argv[0]); - } else { - leakStats = 0; - } - -#if BLD_FEATURE_ALLOC_STATS - ejsPrintAllocReport(ep, 0); - - mprPrintAllocReport(mprGetApp(ep), leakStats, 0); -#endif - -#if BLD_DEBUG - ejsDumpObjects(ep); -#endif - - return 0; -} - -/******************************************************************************/ - -static int runProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc > 1) { - ejsError(ep, EJS_ARG_ERROR, "Bad args: run([quick])"); - return -1; - } - - if (argc == 1) { - ejsIncrementalCollectGarbage(ep); - } else { - ejsCollectGarbage(ep, -1); - } - return 0; -} - -/******************************************************************************/ - -static int usedMemoryProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToInteger(ep, ejsGetUsedMemory(ep)); - return 0; -} - -/******************************************************************************/ - -static int allocatedMemoryProc(Ejs *ep, EjsVar *thisObj, int argc, - EjsVar **argv) -{ -#if BLD_FEATURE_ALLOC_STATS - ejsSetReturnValueToInteger(ep, ejsGetAllocatedMemory(ep)); -#endif - return 0; -} - -/******************************************************************************/ - -static int mprMemoryProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ -#if BLD_FEATURE_ALLOC_STATS - ejsSetReturnValueToInteger(ep, mprGetAllocatedMemory(ep)); -#endif - return 0; -} - -/******************************************************************************/ - -static int peakMprMemoryProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ -#if BLD_FEATURE_ALLOC_STATS - ejsSetReturnValueToInteger(ep, mprGetPeakAllocatedMemory(ep)); -#endif - return 0; -} - -/******************************************************************************/ - -static int getDebugLevel(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToInteger(ep, ep->gc.debugLevel); - return 0; -} - -/******************************************************************************/ - -static int setDebugLevel(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1) { - ejsArgError(ep, "Bad arguments"); - return -1; - } - ep->gc.debugLevel= ejsVarToInteger(argv[0]); - return 0; -} - -/******************************************************************************/ - -static int getEnable(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToBoolean(ep, ep->gc.enable); - return 0; -} - -/******************************************************************************/ - -static int setEnable(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1) { - ejsArgError(ep, "Bad arguments"); - return -1; - } - ep->gc.enable= ejsVarToBoolean(argv[0]); - return 0; -} - -/******************************************************************************/ - -static int getDemandCollect(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToBoolean(ep, ep->gc.enableDemandCollect); - return 0; -} - -/******************************************************************************/ - -static int setDemandCollect(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1) { - ejsArgError(ep, "Bad arguments"); - return -1; - } - ep->gc.enableDemandCollect = ejsVarToBoolean(argv[0]); - return 0; -} - -/******************************************************************************/ - -static int getIdleCollect(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToBoolean(ep, ep->gc.enableIdleCollect); - return 0; -} - -/******************************************************************************/ - -static int setIdleCollect(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1) { - ejsArgError(ep, "Bad arguments"); - return -1; - } - ep->gc.enableIdleCollect = ejsVarToBoolean(argv[0]); - return 0; -} - -/******************************************************************************/ - -static int getWorkQuota(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToInteger(ep, ep->gc.workQuota); - return 0; -} - -/******************************************************************************/ - -static int setWorkQuota(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int quota; - - if (argc != 1) { - ejsArgError(ep, "Bad arguments"); - return -1; - } - quota = ejsVarToInteger(argv[0]); - if (quota < EJS_GC_MIN_WORK_QUOTA && quota != 0) { - ejsArgError(ep, "Bad work quota"); - return -1; - } - - ep->gc.workQuota = quota; - return 0; -} - -/******************************************************************************/ - -static int getMaxMemory(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToInteger(ep, ep->gc.maxMemory); - return 0; -} - -/******************************************************************************/ - -static int setMaxMemory(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int maxMemory; - - if (argc != 1) { - ejsArgError(ep, "Bad arguments"); - return -1; - } - maxMemory = ejsVarToInteger(argv[0]); - if (maxMemory < 0) { - ejsArgError(ep, "Bad maxMemory"); - return -1; - } - - ep->gc.maxMemory = maxMemory; - return 0; -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineGCClass(Ejs *ep) -{ - EjsVar *gcClass; - int flags; - - flags = EJS_NO_LOCAL; - - /* - * NOTE: We create the GC class and define static methods on it. There - * is no object instance - */ - gcClass = ejsDefineClass(ep, "System.GC", "Object", 0); - if (gcClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * MOB -- convert these to properties with accessors when available - */ - ejsDefineCMethod(ep, gcClass, "printStats", printStatsProc, flags); - ejsDefineCMethod(ep, gcClass, "run", runProc, flags); - - ejsDefineCMethod(ep, gcClass, "getUsedMemory", usedMemoryProc, flags); - ejsDefineCMethod(ep, gcClass, "getAllocatedMemory", allocatedMemoryProc, - flags); - ejsDefineCMethod(ep, gcClass, "getMprMemory", mprMemoryProc, flags); - ejsDefineCMethod(ep, gcClass, "getPeakMprMemory", peakMprMemoryProc, flags); - ejsDefineCMethod(ep, gcClass, "debug", debugProc, flags); - -#if (WIN || BREW_SIMULATOR) && BLD_DEBUG - ejsDefineCMethod(ep, gcClass, "check", checkProc, flags); -#endif - - ejsDefineCAccessors(ep, gcClass, "debugLevel", - getDebugLevel, setDebugLevel, flags); - - ejsDefineCAccessors(ep, gcClass, "enable", - getEnable, setEnable, flags); - - ejsDefineCAccessors(ep, gcClass, "demandCollect", - getDemandCollect, setDemandCollect, flags); - - ejsDefineCAccessors(ep, gcClass, "idleCollect", - getIdleCollect, setIdleCollect, flags); - - ejsDefineCAccessors(ep, gcClass, "workQuota", - getWorkQuota, setWorkQuota, flags); - - ejsDefineCAccessors(ep, gcClass, "maxMemory", - getMaxMemory, setMaxMemory, flags); - - return ejsObjHasErrors(gcClass) ? MPR_ERR_CANT_INITIALIZE : 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c deleted file mode 100755 index 6ab8f867e1..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsGlobal.c +++ /dev/null @@ -1,785 +0,0 @@ -/* - * @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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystem.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystem.c deleted file mode 100644 index e035e1c740..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystem.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * @file ejsSystem.c - * @brief System class for the EJS Object Model - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -#if UNUSED -/* - * function int random() - */ - -static int randomProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "random()\n"); - return 0; -} - -/******************************************************************************/ -/* - * function void yield() - */ - -static int yieldProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "yield()\n"); - return 0; -} - -/******************************************************************************/ -/* - * function void sleep(int milliSeconds) - */ - -static int sleepProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ep, "sleep()\n"); - return 0; -} - -#endif -/******************************************************************************/ -/* - * function void exit(int status) - * - * Exit the widget with the given status. All JavaScript processing ceases. - */ - -static int exitProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv) -{ - int status; - - status = 0; - if ((argc == 1) && ejsVarIsInteger(argv[0])) { - status = argv[0]->integer; - } - ejsExit(ep, status); - return 0; -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineSystemClass(Ejs *ep) -{ - EjsVar *systemClass; - - /* - * We create the system class and define static methods on it. - * NOTE: There is no object instance - */ - systemClass = ejsDefineClass(ep, "System", "Object", 0); - if (systemClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - ejsDefineCMethod(ep, systemClass, "exit", exitProc, EJS_NO_LOCAL); - -#if UNUSED - ejsDefineCMethod(ep, systemClass, "random", randomProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, systemClass, "yield", yieldProc, EJS_NO_LOCAL); - ejsDefineCMethod(ep, systemClass, "sleep", sleepProc, EJS_NO_LOCAL); - - /* - * Define properties - */ - ejsSetPropertyToString(systemClass, "name", ""); -#endif - - return ejsObjHasErrors(systemClass) ? MPR_ERR_CANT_INITIALIZE : 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemApp.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemApp.c deleted file mode 100644 index e2f1ceb363..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemApp.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * @file ejsSystemApp.c - * @brief App class - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software Inc, 2005-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/************************************ Code ************************************/ - -int ejsDefineAppClass(Ejs *ep) -{ - EjsVar *appClass; - - appClass = ejsDefineClass(ep, "System.App", "Object", 0); - if (appClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define properties - */ - ejsSetPropertyToString(ep, appClass, "name", BLD_PRODUCT); - ejsSetPropertyToString(ep, appClass, "title", BLD_NAME); - ejsSetPropertyToString(ep, appClass, "version", BLD_VERSION); - - /* - * Command line arguments - */ - ejsSetPropertyToNull(ep, appClass, "args"); - - return ejsObjHasErrors(appClass) ? MPR_ERR_CANT_INITIALIZE : 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemDebug.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemDebug.c deleted file mode 100644 index 5a011e2a2d..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemDebug.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * @file ejsSystemDebug.c - * @brief System.Debug class - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -/* - * function bool isDebugMode() - * MOB -- convert to accessor - */ - -static int isDebugMode(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsTrace(ejs, "isDebugMode()\n"); - ejsSetReturnValueToInteger(ejs, mprGetDebugMode(ejs)); - return 0; -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineDebugClass(Ejs *ejs) -{ - EjsVar *systemDebugClass; - - systemDebugClass = ejsDefineClass(ejs, "System.Debug", "Object", 0); - if (systemDebugClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the class methods - */ - ejsDefineCMethod(ejs, systemDebugClass, "isDebugMode", isDebugMode, - EJS_NO_LOCAL); - - return ejsObjHasErrors(systemDebugClass) ? MPR_ERR_CANT_INITIALIZE : 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemLog.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemLog.c deleted file mode 100644 index 66467f8fcf..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemLog.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * @file ejsSystemLog.c - * @brief System.Log class for the EJS Object Model - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/*********************************** Usage ************************************/ -/* - * System.Log.setLog(path); - * System.Log.enable; - */ -/******************************************************************************/ - -static void logHandler(MPR_LOC_DEC(ctx, loc), int flags, int level, - const char *msg) -{ - MprApp *app; - char *buf; - int len; - - app = mprGetApp(ctx); - if (app->logFile == 0) { - return; - } - - if (flags & MPR_LOG_SRC) { - len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0, - "Log %d: %s\n", level, msg); - - } else if (flags & MPR_ERROR_SRC) { - len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0, - "Error: %s\n", msg); - - } else if (flags & MPR_FATAL_SRC) { - len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0, - "Fatal: %s\n", msg); - - } else if (flags & MPR_ASSERT_SRC) { -#if BLD_FEATURE_ALLOC_LEAK_TRACK - len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0, - "Assertion %s, failed at %s\n", - msg, loc); -#else - len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0, - "Assertion %s, failed\n", msg); -#endif - - } else if (flags & MPR_RAW) { - /* OPT */ - len = mprAllocSprintf(MPR_LOC_PASS(ctx, loc), &buf, 0, - "%s", msg); - - } else { - return; - } - - mprPuts(app->logFile, buf, len); - - mprFree(buf); -} - -/******************************************************************************/ -/************************************ Methods *********************************/ -/******************************************************************************/ -/* - * function int setLog(string path) - */ - -static int setLog(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - const char *path; - MprFile *file; - MprApp *app; - - if (argc != 1 || !ejsVarIsString(argv[0])) { - ejsArgError(ejs, "Usage: setLog(path)"); - return -1; - } - - app = mprGetApp(ejs); - - /* - * Ignore errors if we can't create the log file. - * Use the app context so this will live longer than the interpreter - * MOB -- this leaks files. - */ - path = argv[0]->string; - file = mprOpen(app, path, O_CREAT | O_TRUNC | O_WRONLY, 0664); - if (file) { - app->logFile = file; - mprSetLogHandler(ejs, logHandler); - } - mprLog(ejs, 0, "Test log"); - - return 0; -} - -/******************************************************************************/ -#if UNUSED - -static int enableSetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - if (argc != 1) { - ejsArgError(ejs, "Usage: set(value)"); - return -1; - } - ejsSetProperty(ejs, thisObj, "_enabled", argv[0]); - return 0; -} - -/******************************************************************************/ - -static int enableGetAccessor(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValue(ejs, ejsGetPropertyAsVar(ejs, thisObj, "_enabled")); - return 0; -} - -#endif -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineLogClass(Ejs *ejs) -{ - EjsVar *logClass; - - logClass = ejsDefineClass(ejs, "System.Log", "Object", 0); - if (logClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - ejsDefineCMethod(ejs, logClass, "setLog", setLog, EJS_NO_LOCAL); - -#if UNUSED - EjsProperty *pp; - ejsDefineCAccessors(ejs, logClass, "enable", enableSetAccessor, - enableGetAccessor, EJS_NO_LOCAL); - - pp = ejsSetPropertyToBoolean(ejs, logClass, "_enabled", 0); - ejsMakePropertyEnumerable(pp, 0); -#endif - - return ejsObjHasErrors(logClass) ? MPR_ERR_CANT_INITIALIZE : 0; -} - -/******************************************************************************/ - -/* - * 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 - */ diff --git a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemMemory.c b/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemMemory.c deleted file mode 100755 index d10787b1b4..0000000000 --- a/source4/lib/appweb/ejs-2.0/ejs/system/ejsSystemMemory.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * @file ejsSystemMemory.c - * @brief System.Memory class - */ -/********************************** Copyright *********************************/ -/* - * Copyright (c) Mbedthis Software LLC, 2005-2006. All Rights Reserved. - */ -/********************************** Includes **********************************/ - -#include "ejs.h" - -/****************************** Forward Declarations***************************/ - -static uint getUsedMemory(Ejs *ejs); - -/******************************************************************************/ -/*********************************** Methods *********************************/ -/******************************************************************************/ - -static int getUsedMemoryProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToInteger(ejs, getUsedMemory(ejs)); - return 0; -} - -/******************************************************************************/ - -static int getUsedStackProc(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv) -{ - ejsSetReturnValueToInteger(ejs, mprStackSize(ejs)); - return 0; -} - -/******************************************************************************/ -/* - * Public function - */ - -uint ejsGetAvailableMemory(Ejs *ejs) -{ - EjsVar *memoryClass; - uint ram; - - memoryClass = ejsGetClass(ejs, 0, "System.Memory"); - - ram = ejsGetPropertyAsInteger(ejs, memoryClass, "ram"); - return ram - getUsedMemory(ejs); -} - -/******************************************************************************/ - -static int getAvailableMemoryProc(Ejs *ejs, EjsVar *thisObj, int argc, - EjsVar **argv) -{ - EjsVar *memoryClass; - uint ram; - - memoryClass = ejsGetClass(ejs, 0, "System.Memory"); - - ram = ejsGetPropertyAsInteger(ejs, memoryClass, "ram"); -#if BREW - ejsSetReturnValueToInteger(ejs, ram - getUsedMemory(ejs)); -#else - ejsSetReturnValueToInteger(ejs, 0); -#endif - return 0; -} - -/******************************************************************************/ - -static uint getUsedMemory(Ejs *ejs) -{ -#if BREW - MprApp *app; - IHeap *heap; - uint memInUse; - void *ptr; - - app = mprGetApp(ejs); - ptr = (void*) &heap; - if (ISHELL_CreateInstance(app->shell, AEECLSID_HEAP, (void**) ptr) - == SUCCESS) { - memInUse = IHEAP_GetMemStats(heap); - IHEAP_Release(heap); - } else { - memInUse = 0; - } - - return memInUse; -#else - return 0; -#endif -} - -/******************************************************************************/ -/******************************** Initialization ******************************/ -/******************************************************************************/ - -int ejsDefineMemoryClass(Ejs *ejs) -{ - EjsVar *memoryClass; - uint used; - -#if BREW - MprApp *app; - AEEDeviceInfo *info; - - /* - * Get needed information for class properties. - */ - info = mprAllocType(ejs, AEEDeviceInfo); - if (info == 0) { - return MPR_ERR_CANT_ALLOCATE; - } - info->wStructSize = sizeof(AEEDeviceInfo); - app = mprGetApp(ejs); - ISHELL_GetDeviceInfo(app->shell, info); - used = getUsedMemory(ejs); -#else - used = 0; -#endif - - /* - * Create the class - */ - memoryClass = ejsDefineClass(ejs, "System.Memory", "Object", 0); - if (memoryClass == 0) { - return MPR_ERR_CANT_INITIALIZE; - } - - /* - * Define the class methods - * MOB -- change to accessors - */ - ejsDefineCMethod(ejs, memoryClass, "getUsedStack", getUsedStackProc, - EJS_NO_LOCAL); - ejsDefineCMethod(ejs, memoryClass, "getUsedMemory", getUsedMemoryProc, - EJS_NO_LOCAL); - ejsDefineCMethod(ejs, memoryClass, "getAvailableMemory", - getAvailableMemoryProc, EJS_NO_LOCAL); - - /* - * Define properties - */ -#if BREW - ejsSetPropertyToInteger(ejs, memoryClass, "ram", info->dwRAM); - -#if UNUSED - /* MOB -- delete this */ - ejsSetPropertyToInteger(ejs, memoryClass, "available", - info->dwRAM - used); -#endif -#endif - -#if UNUSED - ejsSetPropertyToInteger(ejs, memoryClass, "used", used); - ejsSetPropertyToInteger(ejs, memoryClass, "flash", 0); -#endif - - return ejsObjHasErrors(memoryClass) ? MPR_ERR_CANT_INITIALIZE : 0; -} - -/******************************************************************************/ - -/* - * 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 - */ |