summaryrefslogtreecommitdiff
path: root/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/ejs/ejsClass.c')
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsClass.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c b/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c
new file mode 100644
index 0000000000..58609adf3f
--- /dev/null
+++ b/source4/lib/appweb/ejs-2.0/ejs/ejsClass.c
@@ -0,0 +1,273 @@
+/*
+ * @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
+ */