summaryrefslogtreecommitdiff
path: root/source4/lib/appweb/ejs
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/appweb/ejs')
-rw-r--r--source4/lib/appweb/ejs/config.h141
-rw-r--r--source4/lib/appweb/ejs/ejs.h136
-rw-r--r--source4/lib/appweb/ejs/ejsInternal.h295
-rw-r--r--source4/lib/appweb/ejs/ejsLex.c923
-rw-r--r--source4/lib/appweb/ejs/ejsLib.c1090
-rw-r--r--source4/lib/appweb/ejs/ejsParser.c2436
-rw-r--r--source4/lib/appweb/ejs/ejsProcs.c704
7 files changed, 0 insertions, 5725 deletions
diff --git a/source4/lib/appweb/ejs/config.h b/source4/lib/appweb/ejs/config.h
deleted file mode 100644
index 8c06d28147..0000000000
--- a/source4/lib/appweb/ejs/config.h
+++ /dev/null
@@ -1,141 +0,0 @@
-#define BLD_PRODUCT "Samba4"
-#define BLD_NAME "Samba4 WEB Applications"
-#define BLD_VERSION "4"
-#define BLD_NUMBER "1"
-#define BLD_TYPE "DEBUG"
-#define BLD_DEFAULTS "normal"
-#define BLD_PACKAGES ""
-#define BLD_APPWEB_CONFIG "normal.conf"
-#define BLD_APPWEB 0
-#define BLD_COMPANY "Mbedthis"
-#define BLD_DEBUG 0
-#define BLD_DIRS "bootstrap include obj bin mpr ejs esp http doc appWeb appWebSamples images"
-#define BLD_HTTP_PORT 7777
-#define BLD_LIB_VERSION "1.0.0"
-#define BLD_SSL_PORT 4443
-#define BLD_CLEAN_INSTALL "0"
-#define BLD_LICENSE "gpl"
-#define BLD_HOST_SYSTEM "i686-pc-linux-gnu"
-#define BLD_BUILD_SYSTEM "i686-pc-linux-gnu"
-#define BLD_HOST_OS "LINUX"
-#define BLD_HOST_CPU_ARCH MPR_CPU_IX86
-#define BLD_HOST_CPU "i686"
-#define BLD_HOST_UNIX 1
-#define BLD_BUILD_OS "LINUX"
-#define BLD_BUILD_CPU_ARCH MPR_CPU_IX86
-#define BLD_BUILD_CPU i686
-#define BLD_BUILD_UNIX 1
-#define BLD_ROOT_PREFIX "/"
-#define BLD_FEATURE_ACCESS_LOG 0
-#define BLD_FEATURE_ADMIN_MODULE 0
-#define BLD_FEATURE_ASPNET_MODULE 0
-#define BLD_FEATURE_ASSERT 1
-#define BLD_FEATURE_AUTH_MODULE 0
-#define BLD_FEATURE_C_API_MODULE 1
-#define BLD_FEATURE_C_API_CLIENT 0
-#define BLD_FEATURE_CGI_MODULE 0
-#define BLD_FEATURE_COMPAT_MODULE 0
-#define BLD_FEATURE_CONFIG_PARSE 0
-#define BLD_FEATURE_CONFIG_SAVE 0
-#define BLD_FEATURE_COOKIE 0
-#define BLD_FEATURE_COPY_MODULE 0
-#define BLD_FEATURE_DIGEST 0
-#define BLD_FEATURE_DLL 0
-#define BLD_FEATURE_EGI_MODULE 0
-#define BLD_FEATURE_EJS 1
-#define BLD_FEATURE_ESP_MODULE 1
-#define BLD_FEATURE_EVAL_PERIOD 30
-#define BLD_FEATURE_FLOATING_POINT 1
-#define BLD_FEATURE_IF_MODIFIED 0
-#define BLD_FEATURE_INT64 1
-#define BLD_FEATURE_KEEP_ALIVE 0
-#define BLD_FEATURE_LEGACY_API 0
-#define BLD_FEATURE_LIB_STDCPP 0
-#define BLD_FEATURE_LICENSE 0
-#define BLD_FEATURE_LOG 0
-#define BLD_FEATURE_MULTITHREAD 0
-#define BLD_FEATURE_MALLOC 0
-#define BLD_FEATURE_MALLOC_STATS 0
-#define BLD_FEATURE_MALLOC_LEAK 0
-#define BLD_FEATURE_MALLOC_HOOK 0
-#define BLD_FEATURE_NUM_TYPE int64_t
-#define BLD_FEATURE_NUM_TYPE_ID MPR_TYPE_INT64
-#define BLD_FEATURE_ROMFS 0
-#define BLD_FEATURE_RUN_AS_SERVICE 0
-#define BLD_FEATURE_SAFE_STRINGS 0
-#define BLD_FEATURE_SAMPLES 0
-#define BLD_FEATURE_SESSION 1
-#define BLD_FEATURE_SHARED 0
-#define BLD_FEATURE_SQUEEZE 0
-#define BLD_FEATURE_SSL_MODULE 0
-#define BLD_FEATURE_STATIC 1
-#define BLD_FEATURE_STATIC_LINK_LIBC 0
-#define BLD_FEATURE_TEST 0
-#define BLD_FEATURE_UPLOAD_MODULE 0
-#define BLD_FEATURE_XDB_MODULE 0
-#define BLD_FEATURE_ADMIN_MODULE_BUILTIN 0
-#define BLD_FEATURE_ASPNET_MODULE_BUILTIN 0
-#define BLD_FEATURE_AUTH_MODULE_BUILTIN 0
-#define BLD_FEATURE_C_API_MODULE_BUILTIN 0
-#define BLD_FEATURE_CGI_MODULE_BUILTIN 0
-#define BLD_FEATURE_COMPAT_MODULE_BUILTIN 0
-#define BLD_FEATURE_COPY_MODULE_BUILTIN 0
-#define BLD_FEATURE_EGI_MODULE_BUILTIN 0
-#define BLD_FEATURE_ESP_MODULE_BUILTIN 0
-#define BLD_FEATURE_SSL_MODULE_BUILTIN 0
-#define BLD_FEATURE_UPLOAD_MODULE_BUILTIN 0
-#define BLD_FEATURE_XDB_MODULE_BUILTIN 0
-#define BLD_FEATURE_ADMIN_MODULE_LOADABLE 0
-#define BLD_FEATURE_ASPNET_MODULE_LOADABLE 0
-#define BLD_FEATURE_AUTH_MODULE_LOADABLE 0
-#define BLD_FEATURE_C_API_MODULE_LOADABLE 0
-#define BLD_FEATURE_CGI_MODULE_LOADABLE 0
-#define BLD_FEATURE_COMPAT_MODULE_LOADABLE 0
-#define BLD_FEATURE_COPY_MODULE_LOADABLE 0
-#define BLD_FEATURE_EGI_MODULE_LOADABLE 0
-#define BLD_FEATURE_ESP_MODULE_LOADABLE 0
-#define BLD_FEATURE_SSL_MODULE_LOADABLE 0
-#define BLD_FEATURE_UPLOAD_MODULE_LOADABLE 0
-#define BLD_FEATURE_XDB_MODULE_LOADABLE 0
-#define BLD_AR_FOR_BUILD "ar"
-#define BLD_CC_FOR_BUILD "cc"
-#define BLD_CSC_FOR_BUILD ""
-#define BLD_JAVAC_FOR_BUILD ""
-#define BLD_LD_FOR_BUILD "ld"
-#define BLD_RANLIB_FOR_BUILD ""
-#define BLD_NM_FOR_BUILD "nm"
-#define BLD_CFLAGS_FOR_BUILD ""
-#define BLD_IFLAGS_FOR_BUILD ""
-#define BLD_LDFLAGS_FOR_BUILD ""
-#define BLD_ARCHIVE_FOR_BUILD ".a"
-#define BLD_EXE_FOR_BUILD ""
-#define BLD_OBJ_FOR_BUILD ".o"
-#define BLD_PIOBJ_FOR_BUILD ".lo"
-#define BLD_CLASS_FOR_BUILD ".class"
-#define BLD_SHLIB_FOR_BUILD ""
-#define BLD_SHOBJ_FOR_BUILD ".so"
-#define BLD_AR_FOR_HOST "ar"
-#define BLD_CC_FOR_HOST "cc"
-#define BLD_CSC_FOR_HOST "csc"
-#define BLD_JAVAC_FOR_HOST "javac"
-#define BLD_LD_FOR_HOST "ld"
-#define BLD_RANLIB_FOR_HOST "true"
-#define BLD_NM_FOR_HOST "nm"
-#define BLD_CFLAGS_FOR_HOST ""
-#define BLD_IFLAGS_FOR_HOST ""
-#define BLD_LDFLAGS_FOR_HOST ""
-#define BLD_ARCHIVE_FOR_HOST ".a"
-#define BLD_EXE_FOR_HOST ""
-#define BLD_OBJ_FOR_HOST ".o"
-#define BLD_PIOBJ_FOR_HOST ".lo"
-#define BLD_CLASS_FOR_HOST ".class"
-#define BLD_SHLIB_FOR_HOST ""
-#define BLD_SHOBJ_FOR_HOST ".so"
-#define BLD_TOOLS_DIR "${BLD_TOP}/bin"
-#define BLD_BIN_DIR "${BLD_TOP}/bin"
-#define BLD_INC_DIR "/usr/include/${BLD_PRODUCT}"
-#define BLD_EXP_OBJ_DIR "${BLD_TOP}/obj"
-
-#ifndef MAX_FLOAT
-#define MAX_FLOAT 3.40282347e+38F
-#endif
diff --git a/source4/lib/appweb/ejs/ejs.h b/source4/lib/appweb/ejs/ejs.h
deleted file mode 100644
index c7b0c54d8e..0000000000
--- a/source4/lib/appweb/ejs/ejs.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * @file ejs.h
- * @brief Primary Embedded Javascript (ECMAScript) header.
- * @overview This Embedded Javascript (EJS) header defines the
- * public API. This API should only be used by those directly
- * using EJS without using Embedded Server Pages (ESP). ESP
- * wraps all relevant APIs to expose a single consistent API.
- * \n\n
- * This API requires the mpr/var.h facilities to create and
- * manage objects and properties.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#ifndef _h_EJS
-#define _h_EJS 1
-
-#include "lib/appweb/mpr/miniMpr.h"
-#include "lib/appweb/mpr/var.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/********************************* Prototypes *********************************/
-
-typedef MprVarHandle EjsId;
-typedef MprVarHandle EjsHandle;
-
-/*
- * Multithreaded lock routines
- */
-typedef void (*EjsLock)(void *lockData);
-typedef void (*EjsUnlock)(void *lockData);
-
-/********************************* Prototypes *********************************/
-/*
- * Module management
- */
-extern int ejsOpen(EjsLock lock, EjsUnlock unlock, void *lockData);
-extern void ejsClose(void);
-extern EjsId ejsOpenEngine(EjsHandle primaryHandle, EjsHandle altHandle);
-extern void ejsCloseEngine(EjsId eid);
-
-void *ejs_save_state(void);
-void ejs_restore_state(void *ptr);
-
-/*
- * Evaluation functions
- */
-extern int ejsEvalFile(EjsId eid, char *path, MprVar *result, char **emsg);
-extern int ejsEvalScript(EjsId eid, char *script, MprVar *result,
- char **emsg);
-extern int ejsRunFunction(int eid, MprVar *obj, const char *functionName,
- MprArray *args);
-
-/*
- * Composite variable get / set routines. Can also use the MPR property
- * routines on an object variable.
- */
-extern MprVar ejsCreateObj(const char *name, int hashSize);
-extern MprVar ejsCreateArray(const char *name, int hashSize);
-extern bool ejsDestroyVar(MprVar *obj);
-extern int ejsCopyVar(EjsId eid, const char *var, MprVar *value,
- bool copyRef);
-extern int ejsReadVar(EjsId eid, const char *var, MprVar *value);
-extern int ejsWriteVar(EjsId eid, const char *var, MprVar *value);
-extern int ejsWriteVarValue(EjsId eid, const char *var, MprVar value);
-extern int ejsDeleteVar(EjsId eid, const char *var);
-
-extern MprVar *ejsGetLocalObject(EjsId eid);
-extern MprVar *ejsGetGlobalObject(EjsId eid);
-
-/*
- * Function routines
- */
-extern void ejsDefineFunction(EjsId eid, const char *functionName,
- char *args, char *body);
-extern void ejsDefineCFunction(EjsId eid, const char *functionName,
- MprCFunction fn, void *thisPtr, int flags);
-extern void ejsDefineStringCFunction(EjsId eid, const char *functionName,
- MprStringCFunction fn, void *thisPtr, int flags);
-extern void *ejsGetThisPtr(EjsId eid);
-extern MprVar *ejsGetReturnValue(EjsId eid);
-extern int ejsGetLineNumber(EjsId eid);
-extern int ejsParseArgs(int argc, char **argv, char *fmt, ...);
-extern void ejsSetErrorMsg(EjsId eid, const char* fmt, ...)
- PRINTF_ATTRIBUTE(2,3);
-extern void ejsSetReturnValue(EjsId eid, MprVar value);
-extern void ejsSetReturnString(EjsId eid, const char *str);
-
-#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/ejsInternal.h b/source4/lib/appweb/ejs/ejsInternal.h
deleted file mode 100644
index 8b66dafdca..0000000000
--- a/source4/lib/appweb/ejs/ejsInternal.h
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * @file ejsInternal.h
- * @brief Private header for Embedded Javascript (ECMAScript)
- * @overview This Embedded Javascript header defines the private Embedded
- * Javascript internal structures.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************* Includes ***********************************/
-
-#ifndef _h_EJS_INTERNAL
-#define _h_EJS_INTERNAL 1
-
-#include "ejs.h"
-
-/********************************** Defines ***********************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Constants
- */
-
-#if BLD_FEATURE_SQUEEZE
- #define EJS_PARSE_INCR 256 /* Growth factor */
- #define EJS_MAX_RECURSE 25 /* Sanity for maximum recursion */
- #define EJS_MAX_ID 128 /* Maximum ID length */
- #define EJS_OBJ_HASH_SIZE 13 /* Object hash table size */
- #define EJS_SMALL_OBJ_HASH_SIZE 11 /* Small object hash size */
- #define EJS_LIST_INCR 8 /* Growth increment for lists */
-#else
- #define EJS_PARSE_INCR 1024 /* Growth factor */
- #define EJS_MAX_RECURSE 100 /* Sanity for maximum recursion */
- #define EJS_MAX_ID 256 /* Maximum ID length */
- #define EJS_OBJ_HASH_SIZE 29 /* Object hash table size */
- #define EJS_SMALL_OBJ_HASH_SIZE 11 /* Small object hash size */
- #define EJS_LIST_INCR 16 /* Growth increment for lists */
-#endif
-#define EJS_TOKEN_STACK 4 /* Put back token 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_FUNCTION_NAME 11 /* functionName */
-#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 */
-
-/*
- * 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 /* ! */
-
-/*
- * States
- */
-#define EJS_STATE_ERR -1 /* Error state */
-#define EJS_STATE_EOF 1 /* 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 /* Function 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_RET 20 /* Return statement */
-
-#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_FOREACH 0x40 /* In foreach */
-#define EJS_FLAGS_NEW 0x80 /* In a new stmt() */
-#define EJS_FLAGS_EXIT 0x100 /* Must exit */
-
-/*
- * Putback token
- */
-
-typedef struct EjsToken {
- char *token; /* Token string */
- int id; /* Token ID */
-} EjsToken;
-
-/*
- * EJ evaluation block structure
- */
-typedef struct ejEval {
- EjsToken putBack[EJS_TOKEN_STACK]; /* Put back token stack */
- int putBackIndex; /* Top of stack index */
- MprStr line; /* Current line */
- int lineLength; /* Current line length */
- int lineNumber; /* Parse line number */
- int lineColumn; /* Column in line */
- MprStr script; /* Input script for parsing */
- char *scriptServp; /* Next token in the script */
- int scriptSize; /* Length of script */
- MprStr tokbuf; /* Current token */
- char *tokEndp; /* Pointer past end of token */
- char *tokServp; /* Pointer to next token char */
- int tokSize; /* Size of token buffer */
- struct ejEval *next; /* used for backtraces */
- const char *procName; /* gives name in backtrace */
-} EjsInput;
-
-/*
- * Function call structure
- */
-typedef struct {
- MprArray *args; /* Args for function */
- MprVar *fn; /* Function definition */
- char *procName; /* Function name */
-} EjsProc;
-
-/*
- * Per EJS structure
- */
-typedef struct ej {
- EjsHandle altHandle; /* alternate callback handle */
- MprVar *currentObj; /* Ptr to current object */
- MprVar *currentProperty; /* Ptr to current property */
- EjsId eid; /* Halloc handle */
- char *error; /* Error message */
- int exitStatus; /* Status to exit() */
- int flags; /* Flags */
- MprArray *frames; /* List of variable frames */
- MprVar *global; /* Global object */
- EjsInput *input; /* Input evaluation block */
- MprVar *local; /* Local object */
- EjsHandle primaryHandle; /* primary callback handle */
- EjsProc *proc; /* Current function */
- MprVar result; /* Variable result */
- void *thisPtr; /* C++ ptr for functions */
- int tid; /* Current token id */
- char *token; /* Pointer to token string */
- MprVar tokenNumber; /* Parsed number */
-} Ejs;
-
-typedef int EjsBlock; /* Scope block id */
-
-/*
- * Function callback when using Alternate handles.
- */
-typedef int (*EjsAltStringCFunction)(EjsHandle userHandle, EjsHandle altHandle,
- int argc, char **argv);
-typedef int (*EjsAltCFunction)(EjsHandle userHandle, EjsHandle altHandle,
- int argc, MprVar **argv);
-
-/******************************** Prototypes **********************************/
-/*
- * Ejs Lex
- */
-extern int ejsLexOpenScript(Ejs* ep, char *script);
-extern void ejsLexCloseScript(Ejs* ep);
-extern int ejsInitInputState(EjsInput *ip);
-extern void ejsLexSaveInputState(Ejs* ep, EjsInput* state);
-extern void ejsLexFreeInputState(Ejs* ep, EjsInput* state);
-extern void ejsLexRestoreInputState(Ejs* ep, EjsInput* state);
-extern int ejsLexGetToken(Ejs* ep, int state);
-extern void ejsLexPutbackToken(Ejs* ep, int tid, char *string);
-
-/*
- * Parsing
- */
-extern MprVar *ejsFindObj(Ejs *ep, int state, const char *property,
- int flags);
-extern MprVar *ejsFindProperty(Ejs *ep, int state, MprVar *obj,
- char *property, int flags);
-extern int ejsGetVarCore(Ejs *ep, const char *var, MprVar **obj,
- MprVar **varValue, int flags);
-extern int ejsParse(Ejs *ep, int state, int flags);
-extern Ejs *ejsPtr(EjsId eid);
-extern void ejsSetExitStatus(int eid, int status);
-extern void ejsSetFlags(int orFlags, int andFlags);
-
-/*
- * Create variable scope blocks
- */
-extern EjsBlock ejsOpenBlock(EjsId eid);
-extern int ejsCloseBlock(EjsId eid, EjsBlock vid);
-extern int ejsEvalBlock(EjsId eid, char *script, MprVar *v, char **err);
-extern int ejsDefineStandardProperties(MprVar *objVar);
-
-/*
- * Error handling
- */
-extern void ejsError(Ejs *ep, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _h_EJS_INTERNAL */
-
-/*
- * 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/ejsLex.c b/source4/lib/appweb/ejs/ejsLex.c
deleted file mode 100644
index b9a363cfc9..0000000000
--- a/source4/lib/appweb/ejs/ejsLex.c
+++ /dev/null
@@ -1,923 +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-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejsInternal.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);
-
-/************************************* Code ***********************************/
-/*
- * Open a new input script
- */
-
-int ejsLexOpenScript(Ejs *ep, char *script)
-{
- EjsInput *ip;
-
- mprAssert(ep);
- mprAssert(script);
-
- if ((ip = mprMalloc(sizeof(EjsInput))) == NULL) {
- return -1;
- }
- memset(ip, 0, sizeof(*ip));
- ip->next = ep->input;
- ep->input = ip;
- ip->procName = ep->proc?ep->proc->procName:NULL;
-
-/*
- * Create the parse token buffer and script buffer
- */
- ip->tokbuf = mprMalloc(EJS_PARSE_INCR);
- ip->tokSize = EJS_PARSE_INCR;
- ip->tokServp = ip->tokbuf;
- ip->tokEndp = ip->tokbuf;
-
- ip->script = mprStrdup(script);
- ip->scriptSize = strlen(script);
- ip->scriptServp = ip->script;
-
- ip->lineNumber = 1;
- ip->lineLength = 0;
- ip->lineColumn = 0;
- ip->line = NULL;
-
- ip->putBackIndex = -1;
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Close the input script
- */
-
-void ejsLexCloseScript(Ejs *ep)
-{
- EjsInput *ip;
- int i;
-
- mprAssert(ep);
-
- ip = ep->input;
- mprAssert(ip);
- ep->input = ip->next;
-
- for (i = 0; i < EJS_TOKEN_STACK; i++) {
- mprFree(ip->putBack[i].token);
- ip->putBack[i].token = 0;
- }
-
- mprFree(ip->line);
- mprFree(ip->tokbuf);
- mprFree(ip->script);
-
- 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++) {
- state->putBack[i].token = mprStrdup(ip->putBack[i].token);
- state->putBack[i].id = ip->putBack[i].id;
- }
- for (; i < EJS_TOKEN_STACK; i++) {
- state->putBack[i].token = 0;
- }
-
- state->line = mprMalloc(ip->lineLength);
- mprStrcpy(state->line, ip->lineLength, ip->line);
-
- state->lineColumn = ip->lineColumn;
- state->lineNumber = ip->lineNumber;
- state->lineLength = ip->lineLength;
-}
-
-/******************************************************************************/
-/*
- * Restore the input state
- */
-
-void ejsLexRestoreInputState(Ejs *ep, EjsInput *state)
-{
- EjsInput *ip;
- int i;
-
- mprAssert(ep);
- mprAssert(state);
-
- ip = ep->input;
- mprAssert(ip);
-
- ip->tokbuf = state->tokbuf;
- ip->tokServp = state->tokServp;
- ip->tokEndp = state->tokEndp;
- ip->tokSize = state->tokSize;
-
- ip->script = state->script;
- ip->scriptServp = state->scriptServp;
- ip->scriptSize = state->scriptSize;
-
- ip->putBackIndex = state->putBackIndex;
- for (i = 0; i < ip->putBackIndex; i++) {
- mprFree(ip->putBack[i].token);
- ip->putBack[i].id = state->putBack[i].id;
- ip->putBack[i].token = mprStrdup(state->putBack[i].token);
- }
-
- mprFree(ip->line);
- ip->line = mprMalloc(state->lineLength);
- mprStrcpy(ip->line, state->lineLength, state->line);
-
- ip->lineColumn = state->lineColumn;
- ip->lineNumber = state->lineNumber;
- ip->lineLength = state->lineLength;
-}
-
-/******************************************************************************/
-/*
- * Free a saved input state
- */
-
-void ejsLexFreeInputState(Ejs *ep, EjsInput *state)
-{
- int i;
-
- mprAssert(ep);
- mprAssert(state);
-
- for (i = 0; i < EJS_TOKEN_STACK; i++) {
- mprFree(state->putBack[i].token);
- }
- state->putBackIndex = -1;
- mprFree(state->line);
- state->lineLength = 0;
- 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", "foreach",
- * "delete", "function", and "return". "new", "in" and "function"
- * done below. "true", "false", "null", "undefined" are handled
- * as global objects.
- *
- * Other reserved words not supported:
- * "break", "case", "catch", "continue", "default", "do",
- * "finally", "instanceof", "switch", "this", "throw", "try",
- * "typeof", "while", "with"
- *
- * ECMA extensions reserved words (not supported):
- * "abstract", "boolean", "byte", "char", "class", "const",
- * "debugger", "double", "enum", "export", "extends",
- * "final", "float", "goto", "implements", "import", "int",
- * "interface", "long", "native", "package", "private",
- * "protected", "public", "short", "static", "super",
- * "synchronized", "throws", "transient", "volatile"
- */
-
-static int checkReservedWord(Ejs *ep, int state, int c, int tid)
-{
- if (state == EJS_STATE_STMT) {
- 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, "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, "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;
- }
- }
- return tid;
-}
-
-/******************************************************************************/
-/*
- * Get the next EJS token
- */
-
-static int getLexicalToken(Ejs *ep, int state)
-{
- MprType type;
- EjsInput *ip;
- int done, tid, c, quote, style, idx;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- ep->tid = -1;
- tid = -1;
- type = BLD_FEATURE_NUM_TYPE_ID;
-
- /*
- * Use a putback tokens first. Don't free strings as caller needs access.
- */
- if (ip->putBackIndex >= 0) {
- idx = ip->putBackIndex;
- tid = ip->putBack[idx].id;
- ep->token = (char*) ip->putBack[idx].token;
- 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) {
- ejsError(ep, "Syntax Error");
- 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) {
- ejsError(ep, "Syntax Error");
- 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) {
- ejsError(ep, "Syntax Error");
- 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;
- }
- ejsError(ep, "Syntax Error");
- 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) {
- ejsError(ep, "Syntax Error");
- 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) {
- ejsError(ep, "Syntax Error");
- 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) {
- ejsError(ep, "Syntax Error");
- 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) {
- ejsError(ep, "Syntax Error");
- 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 '|': /* "||" */
- if ((c = inputGetc(ep)) < 0 || c != '|') {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- tokenAddChar(ep, EJS_COND_OR);
- return EJS_TOK_LOGICAL;
-
- case '&': /* "&&" */
- if ((c = inputGetc(ep)) < 0 || c != '&') {
- ejsError(ep, "Syntax Error");
- return EJS_TOK_ERR;
- }
- tokenAddChar(ep, EJS_COND_AND);
- return EJS_TOK_LOGICAL;
-
- case '\"': /* String quote */
- case '\'':
- quote = c;
- if ((c = inputGetc(ep)) < 0) {
- ejsError(ep, "Syntax Error");
- 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:
- ejsError(ep, "Invalid Escape Sequence");
- 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) {
- ejsError(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') {
- do {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
- } while (isdigit(c) || (tolower(c) >= 'a' && tolower(c) <= 'f'));
-
- mprDestroyVar(&ep->tokenNumber);
- ep->tokenNumber = mprParseVar(ep->token, type);
- inputPutback(ep, c);
- return EJS_TOK_NUMBER;
- }
- if (! isdigit(c)) {
-#if BLD_FEATURE_FLOATING_POINT
- if (c == '.' || tolower(c) == 'e' || c == '+' || c == '-') {
- /* Fall through */
- type = MPR_TYPE_FLOAT;
- } else
-#endif
- {
- mprDestroyVar(&ep->tokenNumber);
- ep->tokenNumber = mprParseVar(ep->token, 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':
- do {
- if (tokenAddChar(ep, c) < 0) {
- return EJS_TOK_ERR;
- }
- if ((c = inputGetc(ep)) < 0) {
- break;
- }
-#if BLD_FEATURE_FLOATING_POINT
- if (c == '.' || tolower(c) == 'e' || tolower(c) == 'f') {
- type = MPR_TYPE_FLOAT;
- }
- } while (isdigit(c) || c == '.' || tolower(c) == 'e' || tolower(c) == 'f' ||
- ((type == MPR_TYPE_FLOAT) && (c == '+' || c == '-')));
-#else
- } while (isdigit(c));
-#endif
-
- mprDestroyVar(&ep->tokenNumber);
- ep->tokenNumber = mprParseVar(ep->token, 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 != '\\') {
- break;
- }
- }
- if (*ep->token == '\0') {
- c = inputGetc(ep);
- break;
- }
- if (! isalpha((int) *ep->token) && *ep->token != '$' &&
- *ep->token != '_') {
- ejsError(ep, "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;
- done++;
- }
- }
-
- /*
- * Putback the last extra character for next time
- */
- inputPutback(ep, c);
- return tid;
-}
-
-/******************************************************************************/
-/*
- * 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;
- int idx;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- ip->putBackIndex += 1;
- idx = ip->putBackIndex;
- ip->putBack[idx].id = tid;
-
- if (ip->putBack[idx].token) {
- if (ip->putBack[idx].token == string) {
- return;
- }
- mprFree(ip->putBack[idx].token);
- }
- ip->putBack[idx].token = mprStrdup(string);
-}
-
-/******************************************************************************/
-/*
- * Add a character to the token buffer
- */
-
-static int tokenAddChar(Ejs *ep, int c)
-{
- EjsInput *ip;
- uchar *oldbuf;
-
- mprAssert(ep);
- ip = ep->input;
- mprAssert(ip);
-
- if (ip->tokEndp >= &ip->tokbuf[ip->tokSize - 1]) {
- ip->tokSize += EJS_PARSE_INCR;
- oldbuf = ip->tokbuf;
- ip->tokbuf = mprRealloc(ip->tokbuf, ip->tokSize);
- if (ip->tokbuf == 0) {
- ejsError(ep, "Token too big");
- return -1;
- }
- ip->tokEndp += (int) ((uchar*) ip->tokbuf - oldbuf);
- ip->tokServp += (int) ((uchar*) ip->tokbuf - oldbuf);
- ep->token += (int) ((uchar*) ip->tokbuf - oldbuf);
- }
- *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 BLD_DEBUG && 0
- if (ip->lineColumn > 0) {
- printf("PARSED: %s\n", ip->line);
- }
-#endif
- ip->lineNumber++;
- ip->lineColumn = 0;
- } else {
- if ((ip->lineColumn + 2) >= ip->lineLength) {
- ip->lineLength += 80;
- ip->line = mprRealloc(ip->line, ip->lineLength * sizeof(char));
- }
- 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++;
- ip->lineColumn--;
- 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/ejsLib.c b/source4/lib/appweb/ejs/ejsLib.c
deleted file mode 100644
index 67d0a4e760..0000000000
--- a/source4/lib/appweb/ejs/ejsLib.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * @file ejs.c
- * @brief Embedded JavaScript (EJS)
- * @overview Main module interface logic.
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejsInternal.h"
-
-#if BLD_FEATURE_EJS
-
-/********************************** Local Data ********************************/
-
-/*
- * These fields must be locked before any access when multithreaded
- */
-static MprVar master; /* Master object */
-static MprArray *ejsList; /* List of ej handles */
-
-#if BLD_FEATURE_MULTITHREAD
-static EjsLock lock;
-static EjsUnlock unlock;
-static void *lockData;
-#define ejsLock() if (lock) { (lock)(lockData); } else
-#define ejsUnlock() if (unlock) { (unlock)(lockData); } else
-#else
-#define ejsLock()
-#define ejsUnlock()
-#endif
-
-
-/*
- save/restore global ejs state - used to cope with simultaneous ejs requests
- this is a workaround for the use of global variables in ejs
-*/
-struct ejs_state_ctx {
- MprVar master;
- MprArray *ejsList;
-};
-
-void *ejs_save_state(void)
-{
- struct ejs_state_ctx *ctx = talloc(talloc_autofree_context(), struct ejs_state_ctx);
- ctx->master = master;
- ctx->ejsList = ejsList;
- return ctx;
-}
-
-void ejs_restore_state(void *ptr)
-{
- struct ejs_state_ctx *ctx = talloc_get_type(ptr, struct ejs_state_ctx);
- master = ctx->master;
- ejsList = ctx->ejsList;
- talloc_free(ctx);
-}
-
-
-/****************************** Forward Declarations **************************/
-
-static char *getNextVarToken(char **next, char *tokBuf, int tokBufLen);
-
-/************************************* Code ***********************************/
-/*
- * Initialize the EJ subsystem
- */
-
-int ejsOpen(EjsLock lockFn, EjsUnlock unlockFn, void *data)
-{
- MprVar *np;
-
-#if BLD_FEATURE_MULTITHREAD
- if (lockFn) {
- lock = lockFn;
- unlock = unlockFn;
- lockData = data;
- }
-#endif
- ejsLock();
-
- /*
- * Master is the top level object (above global). It is used to clone its
- * contents into the global scope for each. This is never visible to the
- * user, so don't use ejsCreateObj().
- */
- master = mprCreateObjVar("master", EJS_SMALL_OBJ_HASH_SIZE);
- if (master.type == MPR_TYPE_UNDEFINED) {
- ejsUnlock();
- return MPR_ERR_CANT_ALLOCATE;
- }
-
- ejsList = mprCreateArray();
- ejsDefineStandardProperties(&master);
-
- /*
- * Make these objects immutable
- */
- np = mprGetFirstProperty(&master, MPR_ENUM_FUNCTIONS | MPR_ENUM_DATA);
- while (np) {
- mprSetVarReadonly(np, 1);
- np = mprGetNextProperty(&master, np, MPR_ENUM_FUNCTIONS |
- MPR_ENUM_DATA);
- }
- ejsUnlock();
- return 0;
-}
-
-/******************************************************************************/
-
-void ejsClose()
-{
- ejsLock();
- mprDestroyArray(ejsList);
- mprDestroyVar(&master);
- ejsUnlock();
-}
-
-/******************************************************************************/
-/*
- * Create and initialize an EJS engine
- */
-
-EjsId ejsOpenEngine(EjsHandle primaryHandle, EjsHandle altHandle)
-{
- MprVar *np;
- Ejs *ep;
-
- ep = (Ejs *)mprMalloc(sizeof(Ejs));
- if (ep == 0) {
- return (EjsId) -1;
- }
- memset(ep, 0, sizeof(Ejs));
-
- ejsLock();
- ep->eid = (EjsId) mprAddToArray(ejsList, ep);
- ejsUnlock();
-
- /*
- * Create array of local variable frames
- */
- ep->frames = mprCreateArray();
- if (ep->frames == 0) {
- ejsCloseEngine(ep->eid);
- return (EjsId) -1;
- }
- ep->primaryHandle = primaryHandle;
- ep->altHandle = altHandle;
-
- /*
- * Create first frame: global variables
- */
- ep->global = (MprVar*) mprMalloc(sizeof(MprVar));
- *ep->global = ejsCreateObj("global", EJS_OBJ_HASH_SIZE);
- if (ep->global->type == MPR_TYPE_UNDEFINED) {
- ejsCloseEngine(ep->eid);
- return (EjsId) -1;
- }
- mprAddToArray(ep->frames, ep->global);
-
- /*
- * Create first local variable frame
- */
- ep->local = (MprVar*) mprMalloc(sizeof(MprVar));
- *ep->local = ejsCreateObj("local", EJS_OBJ_HASH_SIZE);
- if (ep->local->type == MPR_TYPE_UNDEFINED) {
- ejsCloseEngine(ep->eid);
- return (EjsId) -1;
- }
- mprAddToArray(ep->frames, ep->local);
-
- /*
- * Clone all master variables into the global frame. This does a
- * reference copy.
- *
- * ejsDefineStandardProperties(ep->global);
- */
- np = mprGetFirstProperty(&master, MPR_ENUM_FUNCTIONS | MPR_ENUM_DATA);
- while (np) {
- mprCreateProperty(ep->global, np->name, np);
- np = mprGetNextProperty(&master, np, MPR_ENUM_FUNCTIONS |
- MPR_ENUM_DATA);
- }
-
- mprCreateProperty(ep->global, "global", ep->global);
- mprCreateProperty(ep->global, "this", ep->global);
- mprCreateProperty(ep->local, "local", ep->local);
-
- return ep->eid;
-}
-
-/******************************************************************************/
-/*
- * Close an EJS instance
- */
-
-void ejsCloseEngine(EjsId eid)
-{
- Ejs *ep;
- MprVar *vp;
- void **handles;
- int i;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
-
- mprFree(ep->error);
- mprDestroyVar(&ep->result);
- mprDestroyVar(&ep->tokenNumber);
-
- if (ep->local) {
- mprDeleteProperty(ep->local, "local");
- }
- mprDeleteProperty(ep->global, "this");
- mprDeleteProperty(ep->global, "global");
-
- handles = ep->frames->handles;
- for (i = 0; i < ep->frames->max; i++) {
- vp = handles[i];
- if (vp) {
-#if BLD_DEBUG
- if (vp->type == MPR_TYPE_OBJECT && vp->properties->refCount > 1) {
- mprLog(7, "ejsCloseEngine: %s has ref count %d\n",
- vp->name, vp->properties->refCount);
- }
-#endif
- mprDestroyVar(vp);
- mprFree(vp);
- mprRemoveFromArray(ep->frames, i);
- }
- }
- mprDestroyArray(ep->frames);
-
- ejsLock();
- mprRemoveFromArray(ejsList, (int) ep->eid);
- ejsUnlock();
-
- mprFree(ep);
-}
-
-/******************************************************************************/
-/*
- * Evaluate an EJS script file
- */
-
-int ejsEvalFile(EjsId eid, char *path, MprVar *result, char **emsg)
-{
- struct stat sbuf;
- Ejs *ep;
- char *script;
- int rc, fd;
-
- mprAssert(path && *path);
-
- if (emsg) {
- *emsg = NULL;
- }
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- goto error;
- }
-
- if ((fd = open(path, O_RDONLY | O_BINARY, 0666)) < 0) {
- ejsError(ep, "Can't open %s\n", path);
- goto error;
- }
-
- if (stat(path, &sbuf) < 0) {
- close(fd);
- ejsError(ep, "Cant stat %s", path);
- goto error;
- }
-
- if ((script = (char*) mprMalloc(sbuf.st_size + 1)) == NULL) {
- close(fd);
- ejsError(ep, "Cant malloc %d", (int) sbuf.st_size);
- goto error;
- }
-
- if (read(fd, script, sbuf.st_size) != (int) sbuf.st_size) {
- close(fd);
- mprFree(script);
- ejsError(ep, "Error reading %s", path);
- goto error;
- }
-
- script[sbuf.st_size] = '\0';
- close(fd);
-
- rc = ejsEvalBlock(eid, script, result, emsg);
- mprFree(script);
-
- return rc;
-
-/*
- * Error return
- */
-error:
- if(emsg)
- *emsg = mprStrdup(ep->error);
- 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(EjsId eid)
-{
- Ejs *ep;
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
-
- ep->local = (MprVar*) mprMalloc(sizeof(MprVar));
- *ep->local = ejsCreateObj("localBlock", EJS_OBJ_HASH_SIZE);
-
- mprCreateProperty(ep->local, "local", ep->local);
-
- return mprAddToArray(ep->frames, ep->local);
-}
-
-/******************************************************************************/
-/*
- * Close a variable scope block opened via ejsOpenBlock. Pop back the old
- * local variables frame.
- */
-
-int ejsCloseBlock(EjsId eid, int fid)
-{
- Ejs *ep;
-
- if((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- /*
- * Must remove self-references before destroying "local"
- */
- mprDeleteProperty(ep->local, "local");
-
- mprDestroyVar(ep->local);
- mprFree(ep->local);
-
- mprRemoveFromArray(ep->frames, fid);
- ep->local = (MprVar*) ep->frames->handles[ep->frames->used - 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 and emsg are optional. i.e. created local variables will be discarded
- * when this routine returns.
- */
-
-int ejsEvalBlock(EjsId eid, char *script, MprVar *vp, char **emsg)
-{
- int rc, fid;
-
- mprAssert(script);
-
- fid = ejsOpenBlock(eid);
- rc = ejsEvalScript(eid, script, vp, emsg);
- ejsCloseBlock(eid, fid);
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Parse and evaluate a EJS. 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. On errors, emsg will be set to the reason. The caller must
- * free emsg.
- */
-
-int ejsEvalScript(EjsId eid, char *script, MprVar *vp, char **emsg)
-{
- Ejs *ep;
- int state;
- void *endlessLoopTest;
- int loopCounter;
-
- if (emsg) {
- *emsg = NULL;
- }
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- mprDestroyVar(&ep->result);
-
- if (script == 0) {
- return 0;
- }
-
- /*
- * Allocate a new evaluation block, and save the old one
- */
- ejsLexOpenScript(ep, script);
-
- /*
- * Do the actual parsing and evaluation
- */
- loopCounter = 0;
- endlessLoopTest = NULL;
- ep->exitStatus = 0;
-
- do {
- state = ejsParse(ep, EJS_STATE_BEGIN, EJS_FLAGS_EXE);
-
- if (state == EJS_STATE_RET) {
- state = EJS_STATE_EOF;
- }
- /*
- * Stuck parser and endless recursion protection.
- */
- if (endlessLoopTest == ep->input->scriptServp) {
- if (loopCounter++ > 10) {
- state = EJS_STATE_ERR;
- ejsError(ep, "Syntax error");
- }
- } else {
- endlessLoopTest = ep->input->scriptServp;
- loopCounter = 0;
- }
- } while (state != EJS_STATE_EOF && state != EJS_STATE_ERR);
-
- ejsLexCloseScript(ep);
-
- /*
- * Return any error string to the user
- */
- if (state == EJS_STATE_ERR && emsg) {
- *emsg = mprStrdup(ep->error);
- }
-
- if (state == EJS_STATE_ERR) {
- return -1;
- }
-
- if (vp) {
- *vp = ep->result;
- }
-
- return ep->exitStatus;
-}
-
-/******************************************************************************/
-/*
- * Core error handling
- */
-
-static void ejsErrorCore(Ejs* ep, const char *fmt, va_list args)
- PRINTF_ATTRIBUTE(2, 0);
-
-static void ejsErrorCore(Ejs* ep, const char *fmt, va_list args)
-{
- EjsInput *ip;
- char *errbuf, *msgbuf;
- int frame = 0;
-
- mprAssert(ep);
-
- msgbuf = NULL;
- mprAllocVsprintf(&msgbuf, MPR_MAX_STRING, fmt, args);
-
- ip = ep->input;
- mprAllocSprintf(&errbuf, MPR_MAX_STRING, "%s\nBacktrace:\n", msgbuf);
-
- /* form a backtrace */
- while (ip) {
- char *msg2, *ebuf2;
- mprAllocSprintf(&msg2, MPR_MAX_STRING,
- "\t[%2d] %20s:%-4d -> %s\n",
- frame++, ip->procName?ip->procName:"", ip->lineNumber, ip->line);
- ebuf2 = mprRealloc(errbuf, strlen(errbuf) + strlen(msg2) + 1);
- if (ebuf2 == NULL) break;
- errbuf = ebuf2;
- memcpy(errbuf+strlen(errbuf), msg2, strlen(msg2)+1);
- mprFree(msg2);
- ip = ip->next;
- }
- mprFree(ep->error);
- ep->error = errbuf;
- mprFree(msgbuf);
-}
-
-/******************************************************************************/
-/*
- * Internal use function to set the error message
- */
-
-void ejsError(Ejs* ep, const char* fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- ejsErrorCore(ep, fmt, args);
- va_end(args);
-}
-
-/******************************************************************************/
-/*
- * Public routine to set the error message
- */
-
-void ejsSetErrorMsg(EjsId eid, const char* fmt, ...)
-{
- va_list args;
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
- va_start(args, fmt);
- ejsErrorCore(ep, fmt, args);
- va_end(args);
-}
-
-/******************************************************************************/
-/*
- * Get the current line number
- */
-
-int ejsGetLineNumber(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
- return ep->input->lineNumber;
-}
-
-/******************************************************************************/
-/*
- * Return the local object
- */
-
-MprVar *ejsGetLocalObject(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return 0;
- }
- return ep->local;
-}
-
-/******************************************************************************/
-/*
- * Return the global object
- */
-
-MprVar *ejsGetGlobalObject(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return 0;
- }
- return ep->global;
-}
-
-/******************************************************************************/
-/*
- * Copy the value of an object property. Return value is in "value".
- * If deepCopy is true, copy all object/strings. Otherwise, object reference
- * counts are incremented. Callers must always call mprDestroyVar on the
- * return value to prevent leaks.
- *
- * Returns: -1 on errors or if the variable is not found.
- */
-
-int ejsCopyVar(EjsId eid, const char *var, MprVar *value, bool deepCopy)
-{
- Ejs *ep;
- MprVar *vp;
-
- mprAssert(var && *var);
- mprAssert(value);
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- if (ejsGetVarCore(ep, var, 0, &vp, 0) < 0) {
- return -1;
- }
-
- return mprCopyProperty(value, vp, deepCopy);
-}
-
-/******************************************************************************/
-/*
- * Return the value of an object property. Return value is in "value".
- * Objects and strings are not copied and reference counts are not modified.
- * Callers should NOT call mprDestroyVar. Returns: -1 on errors or if the
- * variable is not found.
- */
-
-int ejsReadVar(EjsId eid, const char *var, MprVar *value)
-{
- Ejs *ep;
- MprVar *vp;
-
- mprAssert(var && *var);
- mprAssert(value);
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- if (ejsGetVarCore(ep, var, 0, &vp, 0) < 0) {
- return -1;
- }
-
- return mprReadProperty(vp, value);
-}
-
-/******************************************************************************/
-/*
- * Set a variable that may be an arbitrarily complex object or array reference.
- * Will always define in the top most variable frame.
- */
-
-int ejsWriteVar(EjsId eid, const char *var, MprVar *value)
-{
- Ejs *ep;
- MprVar *vp;
-
- mprAssert(var && *var);
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
-
- if (ejsGetVarCore(ep, var, 0, &vp, EJS_FLAGS_CREATE) < 0) {
- return -1;
- }
- mprAssert(vp);
-
- /*
- * Only copy the value. Don't overwrite the object's name
- */
- mprWriteProperty(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 ejsWriteVarValue(EjsId eid, const char *var, MprVar value)
-{
- return ejsWriteVar(eid, var, &value);
-}
-
-/******************************************************************************/
-/*
- * Delete a variable
- */
-
-int ejsDeleteVar(EjsId eid, const char *var)
-{
- Ejs *ep;
- MprVar *vp;
- MprVar *obj;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return -1;
- }
- if (ejsGetVarCore(ep, var, &obj, &vp, 0) < 0) {
- return -1;
- }
- mprDeleteProperty(obj, vp->name);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value
- */
-
-void ejsSetReturnValue(EjsId eid, MprVar value)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
- mprCopyVar(&ep->result, &value, MPR_SHALLOW_COPY);
-}
-
-/******************************************************************************/
-/*
- * Set the expression return value to a string value
- */
-
-void ejsSetReturnString(EjsId eid, const char *str)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
- mprCopyVarValue(&ep->result, mprCreateStringVar(str, 0), MPR_SHALLOW_COPY);
-}
-
-/******************************************************************************/
-/*
- * Get the expression return value
- */
-
-MprVar *ejsGetReturnValue(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return 0;
- }
- return &ep->result;
-}
-
-/******************************************************************************/
-/*
- * Define a C function. If eid < 0, then update the master object with this
- * function. NOTE: in this case, functionName must be simple without any "." or
- * "[]" elements. If eid >= 0, add to the specified script engine. In this
- * case, functionName can be an arbitrary object reference and can contain "."
- * or "[]".
- */
-
-void ejsDefineCFunction(EjsId eid, const char *functionName, MprCFunction fn,
- void *thisPtr, int flags)
-{
- if (eid < 0) {
- ejsLock();
- mprCreatePropertyValue(&master, functionName,
- mprCreateCFunctionVar(fn, thisPtr, flags));
- ejsUnlock();
- } else {
- ejsWriteVarValue(eid, functionName,
- mprCreateCFunctionVar(fn, thisPtr, flags));
- }
-}
-
-/******************************************************************************/
-/*
- * Define a C function with String arguments
- */
-
-void ejsDefineStringCFunction(EjsId eid, const char *functionName,
- MprStringCFunction fn, void *thisPtr, int flags)
-{
- if (eid < 0) {
- ejsLock();
- mprCreatePropertyValue(&master, functionName,
- mprCreateStringCFunctionVar(fn, thisPtr, flags));
- ejsUnlock();
- } else {
- ejsWriteVarValue(eid, functionName,
- mprCreateStringCFunctionVar(fn, thisPtr, flags));
- }
-}
-
-/******************************************************************************/
-/*
- * Define a JavaScript function. Args should be comma separated.
- * Body should not contain braces.
- */
-
-void ejsDefineFunction(EjsId eid, const char *functionName, char *args,
- char *body)
-{
- MprVar v;
-
- v = mprCreateFunctionVar(args, body, 0);
- if (eid < 0) {
- ejsLock();
- mprCreateProperty(&master, functionName, &v);
- ejsUnlock();
- } else {
- ejsWriteVar(eid, functionName, &v);
- }
- mprDestroyVar(&v);
-}
-
-/******************************************************************************/
-
-void *ejsGetThisPtr(EjsId eid)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return 0;
- }
- return ep->thisPtr;
-}
-
-/******************************************************************************/
-/*
- * Find a variable given a variable name and return the parent object and
- * the variable itself, the variable . This routine supports variable names
- * that may be objects or arrays but may NOT have expressions in the array
- * indicies. Returns -1 on errors or if the variable is not found.
- */
-
-int ejsGetVarCore(Ejs *ep, const char *vname, MprVar **obj,
- MprVar **varValue, int flags)
-{
- MprVar *currentObj;
- MprVar *currentVar;
- char tokBuf[EJS_MAX_ID];
- char *propertyName, *token, *next, *cp, *varName;
-
- if (obj) {
- *obj = 0;
- }
- if (varValue) {
- *varValue = 0;
- }
- currentObj = ejsFindObj(ep, 0, vname, flags);
- currentVar = 0;
- propertyName = 0;
-
- next = varName = mprStrdup(vname);
-
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
-
- while (currentObj != 0 && token != 0 && *token) {
-
- if (*token == '[') {
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
-
- propertyName = token;
- if (*propertyName == '\"') {
- propertyName++;
- if ((cp = strchr(propertyName, '\"')) != 0) {
- *cp = '\0';
- }
- } else if (*propertyName == '\'') {
- propertyName++;
- if ((cp = strchr(propertyName, '\'')) != 0) {
- *cp = '\0';
- }
- }
-
- currentObj = currentVar;
- currentVar = ejsFindProperty(ep, 0, currentObj, propertyName, 0);
-
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- if (*token != ']') {
- mprFree(varName);
- return -1;
- }
-
- } else if (*token == '.') {
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- if (!isalpha((int) token[0]) &&
- token[0] != '_' && token[0] != '$') {
- mprFree(varName);
- return -1;
- }
-
- propertyName = token;
- currentObj = currentVar;
- currentVar = ejsFindProperty(ep, 0, currentObj, token, 0);
-
- } else {
- currentVar = ejsFindProperty(ep, 0, currentObj, token, 0);
- }
- token = getNextVarToken(&next, tokBuf, sizeof(tokBuf));
- }
- mprFree(varName);
-
- if (currentVar == 0 && currentObj >= 0 && flags & EJS_FLAGS_CREATE) {
- currentVar = mprCreatePropertyValue(currentObj, propertyName,
- mprCreateUndefinedVar());
- }
- if (obj) {
- *obj = currentObj;
- }
-
- /*
- * Don't use mprCopyVar as it will copy the data
- */
- if (varValue) {
- *varValue = currentVar;
- }
- return currentVar ? 0 : -1;
-}
-
-/******************************************************************************/
-/*
- * 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;
-}
-
-/******************************************************************************/
-/*
- * Get the EJS structure pointer
- */
-
-Ejs *ejsPtr(EjsId eid)
-{
- Ejs *handle;
- int intId;
-
- intId = (int) eid;
-
- ejsLock();
- mprAssert(0 <= intId && intId < ejsList->max);
-
- if (intId < 0 || intId >= ejsList->max || ejsList->handles[intId] == NULL) {
- mprAssert(0);
- ejsUnlock();
- return NULL;
- }
- handle = ejsList->handles[intId];
- ejsUnlock();
- return handle;
-}
-
-/******************************************************************************/
-/*
- * 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) {
- * mprError("Insufficient args\n");
- * return -1;
- * }
- */
-
-int ejsParseArgs(int argc, char **argv, char *fmt, ...)
-{
- va_list vargs;
- bool *bp;
- char *cp, **sp, *s;
- int *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, bool*);
- 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;
-}
-
-/******************************************************************************/
-
-#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/ejsParser.c b/source4/lib/appweb/ejs/ejsParser.c
deleted file mode 100644
index da922a5728..0000000000
--- a/source4/lib/appweb/ejs/ejsParser.c
+++ /dev/null
@@ -1,2436 +0,0 @@
-/*
- * @file ejsParser.c
- * @brief EJS Parser and Execution
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-
-/********************************** Includes **********************************/
-
-#include "ejsInternal.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-
-static void appendValue(MprVar *v1, MprVar *v2);
-static int evalCond(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs);
-static int evalExpr(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs);
-#if BLD_FEATURE_FLOATING_POINT
-static int evalFloatExpr(Ejs *ep, double l, int rel, double r);
-#endif
-static int evalBoolExpr(Ejs *ep, bool l, int rel, bool r);
-static int evalPtrExpr(Ejs *ep, void *l, int rel, void *r);
-static int evalNumericExpr(Ejs *ep, MprNum l, int rel, MprNum r);
-static int evalStringExpr(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs);
-static int evalFunction(Ejs *ep, MprVar *obj, int flags);
-static void freeProc(EjsProc *proc);
-static int parseArgs(Ejs *ep, int state, int flags);
-static int parseAssignment(Ejs *ep, int state, int flags, char *id,
- char *fullName);
-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 parseForIn(Ejs *ep, int state, int flags);
-static int parseFunctionDec(Ejs *ep, int state, int flags);
-static int parseFunction(Ejs *ep, int state, int flags, char *id);
-static int parseId(Ejs *ep, int state, int flags, char **id,
- char **fullName, int *fullNameLen, int *done);
-static int parseInc(Ejs *ep, int state, int flags);
-static int parseIf(Ejs *ep, int state, int flags, int *done);
-static int parseStmt(Ejs *ep, int state, int flags);
-static void removeNewlines(Ejs *ep, int state);
-static void updateResult(Ejs *ep, int state, int flags, MprVar *vp);
-
-/************************************* Code ***********************************/
-/*
- * Recursive descent parser for EJS
- */
-
-int ejsParse(Ejs *ep, int state, int flags)
-{
- mprAssert(ep);
-
- switch (state) {
- /*
- * Any statement, function arguments or conditional expressions
- */
- case EJS_STATE_STMT:
- if ((state = parseStmt(ep, state, flags)) != EJS_STATE_STMT_DONE &&
- state != EJS_STATE_EOF && state != EJS_STATE_STMT_BLOCK_DONE &&
- state != EJS_STATE_RET) {
- state = EJS_STATE_ERR;
- }
- break;
-
- case EJS_STATE_DEC:
- if ((state = parseStmt(ep, state, flags)) != EJS_STATE_DEC_DONE &&
- state != EJS_STATE_EOF) {
- state = EJS_STATE_ERR;
- }
- break;
-
- case EJS_STATE_EXPR:
- if ((state = parseStmt(ep, state, flags)) != EJS_STATE_EXPR_DONE &&
- state != EJS_STATE_EOF) {
- state = EJS_STATE_ERR;
- }
- break;
-
- /*
- * Variable declaration list
- */
- case EJS_STATE_DEC_LIST:
- state = parseDeclaration(ep, state, flags);
- break;
-
- /*
- * Function argument string
- */
- case EJS_STATE_ARG_LIST:
- state = parseArgs(ep, state, flags);
- break;
-
- /*
- * Logical condition list (relational operations separated by &&, ||)
- */
- case EJS_STATE_COND:
- state = parseCond(ep, state, flags);
- break;
-
- /*
- * Expression list
- */
- case EJS_STATE_RELEXP:
- state = parseExpr(ep, state, flags);
- break;
- }
-
- if (state == EJS_STATE_ERR && ep->error == NULL) {
- ejsError(ep, "Syntax error");
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse any statement including functions and simple relational operations
- */
-
-static int parseStmt(Ejs *ep, int state, int flags)
-{
- EjsProc *saveProc;
- MprVar *vp, *saveObj;
- char *id, *fullName, *initToken;
- int done, expectSemi, tid, fullNameLen, rel;
- int initId;
-
- mprAssert(ep);
-
- expectSemi = 0;
- saveProc = NULL;
- id = 0;
- fullName = 0;
- fullNameLen = 0;
-
- ep->currentObj = 0;
- ep->currentProperty = 0;
-
- for (done = 0; !done && state != EJS_STATE_ERR; ) {
- tid = ejsLexGetToken(ep, state);
-
- switch (tid) {
- default:
- ejsLexPutbackToken(ep, EJS_TOK_EXPR, ep->token);
- done++;
- break;
-
- case EJS_TOK_EXPR:
- rel = (int) *ep->token;
- if (state == EJS_STATE_EXPR) {
- ejsLexPutbackToken(ep, EJS_TOK_EXPR, ep->token);
- }
- done++;
- break;
-
- case EJS_TOK_LOGICAL:
- ejsLexPutbackToken(ep, tid, ep->token);
- done++;
- break;
-
- case EJS_TOK_ERR:
- state = EJS_STATE_ERR;
- done++;
- break;
-
- case EJS_TOK_EOF:
- state = EJS_STATE_EOF;
- done++;
- break;
-
- 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, tid, ep->token);
- }
- done++;
- break;
-
- case EJS_TOK_PERIOD:
- if (flags & EJS_FLAGS_EXE) {
- if (ep->currentProperty == 0) {
- ejsError(ep, "Undefined object \"%s\"\n", id);
- goto error;
- }
- }
- ep->currentObj = ep->currentProperty;
-
- if ((tid = ejsLexGetToken(ep, state)) != EJS_TOK_ID) {
- ejsError(ep, "Bad property after '.': %s\n", ep->token);
- goto error;
- }
- mprFree(id);
- id = mprStrdup(ep->token);
-
- vp = ejsFindProperty(ep, state, ep->currentObj, id, flags);
- updateResult(ep, state, flags, vp);
-
-#if BLD_DEBUG
- fullNameLen = mprReallocStrcat(&fullName, MPR_MAX_VAR, fullNameLen,
- 0, ".", NULL);
-#endif
-
- ep->currentProperty = vp;
- ejsLexPutbackToken(ep, tid, ep->token);
- break;
-
- case EJS_TOK_LBRACKET:
- ep->currentObj = ep->currentProperty;
- saveObj = ep->currentObj;
- if (ejsParse(ep, EJS_STATE_RELEXP, flags) != EJS_STATE_RELEXP_DONE){
- goto error;
- }
- ep->currentObj = saveObj;
-
- mprFree(id);
- mprVarToString(&id, MPR_MAX_STRING, 0, &ep->result);
-
- if (id[0] == '\0') {
- if (flags & EJS_FLAGS_EXE) {
- ejsError(ep,
- "[] expression evaluates to the empty string\n");
- goto error;
- }
- } else {
- vp = ejsFindProperty(ep, state, ep->currentObj, id, flags);
- ep->currentProperty = vp;
- updateResult(ep, state, flags, vp);
- }
-
-#if BLD_DEBUG
- if (id[0] && strlen(id) < (MPR_MAX_VAR / 2)) {
- /*
- * If not executing yet, id may not be known
- */
- fullNameLen = mprReallocStrcat(&fullName, MPR_MAX_VAR,
- fullNameLen, 0, "[", id, "]", NULL);
- }
-#endif
-
- if ((tid = ejsLexGetToken(ep, state)) != EJS_TOK_RBRACKET) {
- ejsError(ep, "Missing ']'\n");
- goto error;
- }
- break;
-
- case EJS_TOK_ID:
- state = parseId(ep, state, flags, &id, &fullName, &fullNameLen,
- &done);
- if (done && state == EJS_STATE_STMT) {
- expectSemi++;
- }
- break;
-
- case EJS_TOK_ASSIGNMENT:
- state = parseAssignment(ep, state, flags, id, fullName);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- done++;
- }
- break;
-
- case EJS_TOK_INC_DEC:
- state = parseInc(ep, state, flags);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- }
- break;
-
- case EJS_TOK_NEW:
- if (ejsParse(ep, EJS_STATE_EXPR, flags | EJS_FLAGS_NEW)
- != EJS_STATE_EXPR_DONE) {
- goto error;
- }
- break;
-
- case EJS_TOK_DELETE:
- if (ejsParse(ep, EJS_STATE_EXPR,
- flags | EJS_FLAGS_DELETE) != EJS_STATE_EXPR_DONE) {
- goto error;
- }
- if (flags & EJS_FLAGS_EXE) {
- mprDeleteProperty(ep->currentObj, ep->currentProperty->name);
- }
- done++;
- break;
-
- case EJS_TOK_FUNCTION:
- state = parseFunctionDec(ep, state, flags);
- done++;
- break;
-
- case EJS_TOK_LITERAL:
- /*
- * Set the result to the string literal
- */
- mprCopyVarValue(&ep->result, mprCreateStringVar(ep->token, 0),
- MPR_SHALLOW_COPY);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- }
- done++;
- break;
-
- case EJS_TOK_NUMBER:
- /*
- * Set the result to the parsed number
- */
- mprCopyVar(&ep->result, &ep->tokenNumber, 0);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- }
- done++;
- break;
-
- case EJS_TOK_FUNCTION_NAME:
- state = parseFunction(ep, state, flags, id);
- if (state == EJS_STATE_STMT) {
- expectSemi++;
- }
- if (ep->flags & EJS_FLAGS_EXIT) {
- state = EJS_STATE_RET;
- }
- done++;
- break;
-
- case EJS_TOK_IF:
- state = parseIf(ep, state, flags, &done);
- if (state == EJS_STATE_RET) {
- goto doneParse;
- }
- break;
-
- case EJS_TOK_FOR:
- if (state != EJS_STATE_STMT) {
- goto error;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_LPAREN) {
- goto error;
- }
- /*
- * Need to peek 2-3 tokens ahead and see if this is a
- * for ([var] x in set)
- * or
- * for (init ; whileCond; incr)
- */
- initId = ejsLexGetToken(ep, EJS_STATE_EXPR);
- if (initId == EJS_TOK_ID && strcmp(ep->token, "var") == 0) {
- /* Simply eat var tokens */
- initId = ejsLexGetToken(ep, EJS_STATE_EXPR);
- }
- initToken = mprStrdup(ep->token);
-
- tid = ejsLexGetToken(ep, EJS_STATE_EXPR);
-
- ejsLexPutbackToken(ep, tid, ep->token);
- ejsLexPutbackToken(ep, initId, initToken);
- mprFree(initToken);
-
- if (tid == EJS_TOK_IN) {
- if ((state = parseForIn(ep, state, flags)) < 0) {
- goto error;
- }
- } else {
- if ((state = parseFor(ep, state, flags)) < 0) {
- goto error;
- }
- }
- done++;
- break;
-
- case EJS_TOK_VAR:
- if (ejsParse(ep, EJS_STATE_DEC_LIST, flags)
- != EJS_STATE_DEC_LIST_DONE) {
- goto error;
- }
- done++;
- break;
-
- case EJS_TOK_COMMA:
- ejsLexPutbackToken(ep, tid, ep->token);
- done++;
- break;
-
- case EJS_TOK_LPAREN:
- if (state == EJS_STATE_EXPR) {
- if (ejsParse(ep, EJS_STATE_RELEXP, flags)
- != EJS_STATE_RELEXP_DONE) {
- goto error;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- goto error;
- }
- }
- done++;
- break;
-
- case EJS_TOK_RPAREN:
- ejsLexPutbackToken(ep, tid, ep->token);
- done++;
- break;
-
- case EJS_TOK_LBRACE:
- /*
- * This handles any code in braces except "if () {} else {}"
- */
- if (state != EJS_STATE_STMT) {
- goto error;
- }
-
- /*
- * Parse will return EJS_STATE_STMT_BLOCK_DONE when the RBRACE
- * is seen.
- */
- do {
- state = ejsParse(ep, EJS_STATE_STMT, flags);
- } while (state == EJS_STATE_STMT_DONE);
-
- if (state != EJS_STATE_RET) {
- if (ejsLexGetToken(ep, state) != EJS_TOK_RBRACE) {
- goto error;
- }
- state = EJS_STATE_STMT_DONE;
- }
- done++;
- break;
-
- case EJS_TOK_RBRACE:
- if (state == EJS_STATE_STMT) {
- ejsLexPutbackToken(ep, tid, ep->token);
- state = EJS_STATE_STMT_BLOCK_DONE;
- done++;
- break;
- }
- goto error;
-
- case EJS_TOK_RETURN:
- if (ejsParse(ep, EJS_STATE_RELEXP, flags)
- != EJS_STATE_RELEXP_DONE) {
- goto error;
- }
- if (flags & EJS_FLAGS_EXE) {
- while (ejsLexGetToken(ep, state) != EJS_TOK_EOF) {
- ;
- }
- state = EJS_STATE_RET;
- done++;
- }
- break;
- }
- }
-
- if (expectSemi) {
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_SEMI && tid != EJS_TOK_NEWLINE &&
- tid != EJS_TOK_EOF) {
- goto error;
- }
-
- /*
- * Skip newline after semi-colon
- */
- removeNewlines(ep, state);
- }
-
-/*
- * Free resources and return the correct status
- */
-doneParse:
- mprFree(id);
- mprFree(fullName);
-
- /*
- * Advance the state
- */
- switch (state) {
- case EJS_STATE_STMT:
- return EJS_STATE_STMT_DONE;
-
- case EJS_STATE_DEC:
- return EJS_STATE_DEC_DONE;
-
- case EJS_STATE_EXPR:
- return EJS_STATE_EXPR_DONE;
-
- case EJS_STATE_STMT_DONE:
- case EJS_STATE_STMT_BLOCK_DONE:
- case EJS_STATE_EOF:
- case EJS_STATE_RET:
- return state;
-
- default:
- return EJS_STATE_ERR;
- }
-
-/*
- * Common error exit
- */
-error:
- state = EJS_STATE_ERR;
- goto doneParse;
-}
-
-/******************************************************************************/
-/*
- * Parse function arguments
- */
-
-static int parseArgs(Ejs *ep, int state, int flags)
-{
- 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;
- }
-
- state = ejsParse(ep, EJS_STATE_RELEXP, flags);
- if (state == EJS_STATE_EOF || state == EJS_STATE_ERR) {
- return state;
- }
- if (state == EJS_STATE_RELEXP_DONE) {
- if (flags & EJS_FLAGS_EXE) {
- mprAssert(ep->proc->args);
- mprAddToArray(ep->proc->args,
- mprDupVar(&ep->result, MPR_SHALLOW_COPY));
- }
- }
- /*
- * 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) {
- return EJS_STATE_ERR;
- }
- return EJS_STATE_ARG_LIST_DONE;
-}
-
-/******************************************************************************/
-/*
- * Parse an assignment statement
- */
-
-static int parseAssignment(Ejs *ep, int state, int flags, char *id,
- char *fullName)
-{
- MprVar *vp, *saveProperty, *saveObj;
-
- if (id == 0) {
- return -1;
- }
-
- saveObj = ep->currentObj;
- saveProperty = ep->currentProperty;
- if (ejsParse(ep, EJS_STATE_RELEXP, flags | EJS_FLAGS_ASSIGNMENT)
- != EJS_STATE_RELEXP_DONE) {
- return -1;
- }
- ep->currentObj = saveObj;
- ep->currentProperty = saveProperty;
-
- if (! (flags & EJS_FLAGS_EXE)) {
- return state;
- }
-
- if (ep->currentProperty) {
- /*
- * Update the variable. Update the property name if not
- * yet defined.
- */
- if (ep->currentProperty->name == 0 ||
- ep->currentProperty->name[0] == '\0') {
- mprSetVarName(ep->currentProperty, id);
- }
- if (mprWriteProperty(ep->currentProperty, &ep->result) < 0){
- ejsError(ep, "Can't write to variable\n");
- return -1;
- }
-
- } else {
- /*
- * Create the variable
- */
- if (ep->currentObj) {
- if (ep->currentObj->type != MPR_TYPE_OBJECT) {
- if (strcmp(ep->currentObj->name, "session") == 0) {
- ejsError(ep, "Variable \"%s\" is not an array or object."
- "If using ESP, you need useSession(); in your page.",
- ep->currentObj->name);
- } else {
- ejsError(ep, "Variable \"%s\" is not an array or object",
- ep->currentObj->name);
- }
- return -1;
- }
- vp = mprCreateProperty(ep->currentObj, id, &ep->result);
-
- } else {
- /*
- * Standard says: "var x" means declare locally.
- * "x = 2" means declare globally if x is undefined.
- */
- if (state == EJS_STATE_DEC) {
- vp = mprCreateProperty(ep->local, id, &ep->result);
- } else {
- vp = mprCreateProperty(ep->global, id, &ep->result);
- }
- }
-#if BLD_DEBUG
- mprSetVarFullName(vp, fullName);
-#endif
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse conditional expression (relational ops separated by ||, &&)
- */
-
-static int parseCond(Ejs *ep, int state, int flags)
-{
- MprVar lhs, rhs;
- int tid, operator;
-
- mprAssert(ep);
-
- mprDestroyVar(&ep->result);
- rhs = lhs = mprCreateUndefinedVar();
- 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 != EJS_STATE_RELEXP_DONE) {
- state = EJS_STATE_ERR;
- break;
- }
-
- if (operator > 0) {
- mprCopyVar(&rhs, &ep->result, MPR_SHALLOW_COPY);
- if (evalCond(ep, &lhs, operator, &rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- }
- mprCopyVar(&lhs, &ep->result, MPR_SHALLOW_COPY);
-
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_LOGICAL) {
- operator = (int) *ep->token;
-
- } else if (tid == EJS_TOK_RPAREN || tid == EJS_TOK_SEMI) {
- ejsLexPutbackToken(ep, tid, ep->token);
- state = EJS_STATE_COND_DONE;
- break;
-
- } else {
- ejsLexPutbackToken(ep, tid, ep->token);
- }
- tid = (state == EJS_STATE_RELEXP_DONE);
-
- } while (state == EJS_STATE_RELEXP_DONE);
-
- mprDestroyVar(&lhs);
- mprDestroyVar(&rhs);
- 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;
- *
- * 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) {
- 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
- */
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_SEMI) {
- return EJS_STATE_DEC_LIST_DONE;
- } else if (tid != EJS_TOK_COMMA) {
- return EJS_STATE_ERR;
- }
- } while (tid == EJS_TOK_COMMA);
-
- if (tid != EJS_TOK_SEMI) {
- return EJS_STATE_ERR;
- }
- return EJS_STATE_DEC_LIST_DONE;
-}
-
-/******************************************************************************/
-/*
- * Parse expression (leftHandSide operator rightHandSide)
- */
-
-static int parseExpr(Ejs *ep, int state, int flags)
-{
- MprVar lhs, rhs;
- int rel, tid;
-
- mprAssert(ep);
-
- mprDestroyVar(&ep->result);
- rhs = lhs = mprCreateUndefinedVar();
- rel = 0;
- tid = 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 (tid == EJS_TOK_LOGICAL) {
- state = ejsParse(ep, EJS_STATE_RELEXP, flags);
- if (state != EJS_STATE_RELEXP_DONE) {
- state = EJS_STATE_ERR;
- break;
- }
- } else {
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_EXPR && (int) *ep->token == EJS_EXPR_MINUS) {
- lhs = mprCreateIntegerVar(0);
- rel = (int) *ep->token;
- } else {
- ejsLexPutbackToken(ep, tid, ep->token);
- }
-
- state = ejsParse(ep, EJS_STATE_EXPR, flags);
- if (state != EJS_STATE_EXPR_DONE) {
- state = EJS_STATE_ERR;
- break;
- }
- }
-
- if (rel > 0) {
- mprCopyVar(&rhs, &ep->result, MPR_SHALLOW_COPY);
- if (tid == EJS_TOK_LOGICAL) {
- if (evalCond(ep, &lhs, rel, &rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- } else {
- if (evalExpr(ep, &lhs, rel, &rhs) < 0) {
- state = EJS_STATE_ERR;
- break;
- }
- }
- }
- mprCopyVar(&lhs, &ep->result, MPR_SHALLOW_COPY);
-
- if ((tid = ejsLexGetToken(ep, state)) == EJS_TOK_EXPR ||
- tid == EJS_TOK_INC_DEC || tid == EJS_TOK_LOGICAL) {
- rel = (int) *ep->token;
-
- } else {
- ejsLexPutbackToken(ep, tid, ep->token);
- state = EJS_STATE_RELEXP_DONE;
- }
-
- } while (state == EJS_STATE_EXPR_DONE);
-
- mprDestroyVar(&lhs);
- mprDestroyVar(&rhs);
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse the "for ... in" statement. Format for the statement is:
- *
- * for (var in expr) {
- * body;
- * }
- */
-
-static int parseForIn(Ejs *ep, int state, int flags)
-{
- EjsInput endScript, bodyScript;
- MprVar *iteratorVar, *setVar, *vp, v;
- int forFlags, tid;
-
- mprAssert(ep);
-
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_ID) {
- return -1;
- }
- ejsLexPutbackToken(ep, tid, ep->token);
-
- if (ejsParse(ep, EJS_STATE_EXPR, EJS_FLAGS_FOREACH | EJS_FLAGS_EXE)
- != EJS_STATE_EXPR_DONE) {
- return -1;
- }
- if (ep->currentProperty == 0) {
- return -1;
- }
- iteratorVar = ep->currentProperty;
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_IN) {
- return -1;
- }
-
- /*
- * Get the set
- */
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_ID) {
- return -1;
- }
- ejsLexPutbackToken(ep, tid, ep->token);
-
- if (ejsParse(ep, EJS_STATE_EXPR, flags) != EJS_STATE_EXPR_DONE) {
- return -1;
- }
- if (ep->currentProperty == 0 && flags & EJS_FLAGS_EXE) {
- return -1;
- }
- setVar = ep->currentProperty;
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- return -1;
- }
-
- /*
- * Parse the body and remember the end of the body script
- */
- forFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, &bodyScript);
- if (ejsParse(ep, EJS_STATE_STMT, forFlags) != EJS_STATE_STMT_DONE) {
- ejsLexFreeInputState(ep, &bodyScript);
- return -1;
- }
- ejsInitInputState(&endScript);
- ejsLexSaveInputState(ep, &endScript);
-
- /*
- * Now actually do the for loop.
- */
- if (flags & EJS_FLAGS_EXE) {
- if (setVar->type == MPR_TYPE_OBJECT) {
- vp = mprGetFirstProperty(setVar, MPR_ENUM_DATA);
- while (vp) {
- if (strcmp(vp->name, "length") != 0) {
- v = mprCreateStringVar(vp->name, 0);
- if (mprWriteProperty(iteratorVar, &v) < 0) {
- ejsError(ep, "Can't write to variable\n");
- ejsLexFreeInputState(ep, &bodyScript);
- ejsLexFreeInputState(ep, &endScript);
- return -1;
- }
-
- ejsLexRestoreInputState(ep, &bodyScript);
- switch (ejsParse(ep, EJS_STATE_STMT, flags)) {
- case EJS_STATE_RET:
- return EJS_STATE_RET;
- case EJS_STATE_STMT_DONE:
- break;
- default:
- ejsLexFreeInputState(ep, &endScript);
- ejsLexFreeInputState(ep, &bodyScript);
- return -1;
- }
- }
- vp = mprGetNextProperty(setVar, vp, MPR_ENUM_DATA);
- }
- } else {
- ejsError(ep, "Variable \"%s\" is not an array or object",
- setVar->name);
- ejsLexFreeInputState(ep, &endScript);
- ejsLexFreeInputState(ep, &bodyScript);
- return -1;
- }
- }
- ejsLexRestoreInputState(ep, &endScript);
-
- ejsLexFreeInputState(ep, &endScript);
- ejsLexFreeInputState(ep, &bodyScript);
-
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse the for statement. Format for the expression is:
- *
- * for (initial; condition; incr) {
- * body;
- * }
- */
-
-static int parseFor(Ejs *ep, int state, int flags)
-{
- EjsInput condScript, endScript, bodyScript, incrScript;
- int forFlags, cond;
-
- ejsInitInputState(&endScript);
- ejsInitInputState(&bodyScript);
- ejsInitInputState(&incrScript);
- ejsInitInputState(&condScript);
-
- mprAssert(ep);
-
- /*
- * Evaluate the for loop initialization statement
- */
- if (ejsParse(ep, EJS_STATE_EXPR, flags) != EJS_STATE_EXPR_DONE) {
- return -1;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_SEMI) {
- return -1;
- }
-
- /*
- * 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 (ejsParse(ep, EJS_STATE_COND, flags) != EJS_STATE_COND_DONE) {
- goto error;
- }
- cond = (ep->result.boolean != 0);
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_SEMI) {
- goto error;
- }
-
- /*
- * Don't execute the loop increment statement or the body
- * first time.
- */
- forFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, &incrScript);
- if (ejsParse(ep, EJS_STATE_EXPR, forFlags) != EJS_STATE_EXPR_DONE) {
- goto error;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- goto error;
- }
-
- /*
- * Parse the body and remember the end of the body script
- */
- ejsLexSaveInputState(ep, &bodyScript);
- if (ejsParse(ep, EJS_STATE_STMT, forFlags) != EJS_STATE_STMT_DONE) {
- goto error;
- }
- 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);
-
- switch (ejsParse(ep, EJS_STATE_STMT, flags)) {
- case EJS_STATE_RET:
- return EJS_STATE_RET;
- case EJS_STATE_STMT_DONE:
- break;
- default:
- goto error;
- }
- /*
- * Evaluate the increment script
- */
- ejsLexRestoreInputState(ep, &incrScript);
- if (ejsParse(ep, EJS_STATE_EXPR, flags) != EJS_STATE_EXPR_DONE){
- goto error;
- }
- /*
- * Evaluate the condition
- */
- ejsLexRestoreInputState(ep, &condScript);
- if (ejsParse(ep, EJS_STATE_COND, flags) != EJS_STATE_COND_DONE) {
- goto error;
- }
- mprAssert(ep->result.type == MPR_TYPE_BOOL);
- cond = (ep->result.boolean != 0);
- }
-
- ejsLexRestoreInputState(ep, &endScript);
-
-done:
- ejsLexFreeInputState(ep, &condScript);
- ejsLexFreeInputState(ep, &incrScript);
- ejsLexFreeInputState(ep, &endScript);
- ejsLexFreeInputState(ep, &bodyScript);
- return state;
-
-error:
- state = EJS_STATE_ERR;
- goto done;
-}
-
-/******************************************************************************/
-/*
- * Parse a function declaration
- */
-
-static int parseFunctionDec(Ejs *ep, int state, int flags)
-{
- EjsInput endScript, bodyScript;
- MprVar v, *currentObj, *vp;
- char *procName;
- int len, tid, bodyFlags;
-
- mprAssert(ep);
- mprAssert(ejsPtr(ep->eid));
-
- /*
- * function <name>(arg, arg, arg) { body };
- * function name(arg, arg, arg) { body };
- */
-
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_ID) {
- procName = mprStrdup(ep->token);
- tid = ejsLexGetToken(ep, state);
- } else {
- procName = 0;
- }
- if (tid != EJS_TOK_LPAREN) {
- mprFree(procName);
- return EJS_STATE_ERR;
- }
-
- /*
- * Hand craft the function value structure.
- */
- v = mprCreateFunctionVar(0, 0, 0);
- tid = ejsLexGetToken(ep, state);
- while (tid == EJS_TOK_ID) {
- mprAddToArray(v.function.args, mprStrdup(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);
- mprDestroyVar(&v);
- 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);
- mprDestroyVar(&v);
- return EJS_STATE_ERR;
- }
-
- /*
- * Register the function name early to allow for recursive
- * function calls (see note in ECMA standard, page 71)
- */
- if (!(flags & EJS_FLAGS_ASSIGNMENT)) {
- currentObj = ejsFindObj(ep, 0, procName, flags);
- vp = mprSetProperty(currentObj, procName, &v);
- }
-
- /*
- * Parse the function body. Turn execute off.
- */
- bodyFlags = flags & ~EJS_FLAGS_EXE;
- ejsLexSaveInputState(ep, &bodyScript);
-
- do {
- state = ejsParse(ep, EJS_STATE_STMT, bodyFlags);
- } while (state == EJS_STATE_STMT_DONE);
-
- tid = ejsLexGetToken(ep, state);
- if (state != EJS_STATE_STMT_BLOCK_DONE || tid != EJS_TOK_RBRACE) {
- mprFree(procName);
- mprDestroyVar(&v);
- ejsLexFreeInputState(ep, &bodyScript);
- return EJS_STATE_ERR;
- }
- ejsLexSaveInputState(ep, &endScript);
-
- /*
- * Save the function body between the starting and ending parse positions.
- * Overwrite the trailing '}' with a null.
- */
- len = endScript.scriptServp - bodyScript.scriptServp;
- v.function.body = mprMalloc(len + 1);
- memcpy(v.function.body, bodyScript.scriptServp, len);
-
- if (len <= 0) {
- v.function.body[0] = '\0';
- } else {
- v.function.body[len - 1] = '\0';
- }
- ejsLexFreeInputState(ep, &bodyScript);
- ejsLexFreeInputState(ep, &endScript);
-
- /*
- * If we are in an assignment, don't register the function name, rather
- * return the function structure in the parser result.
- */
- if (flags & EJS_FLAGS_ASSIGNMENT) {
- mprCopyVar(&ep->result, &v, MPR_SHALLOW_COPY);
- } else {
- currentObj = ejsFindObj(ep, 0, procName, flags);
- vp = mprSetProperty(currentObj, procName, &v);
- }
-
- mprFree(procName);
- mprDestroyVar(&v);
-
- return EJS_STATE_STMT;
-}
-
-/******************************************************************************/
-/*
- * Parse a function name and invoke the function
- */
-
-static int parseFunction(Ejs *ep, int state, int flags, char *id)
-{
- EjsProc proc, *saveProc;
- MprVar *saveObj;
-
- /*
- * Must save any current ep->proc value for the current stack frame
- * to allow for recursive function calls.
- */
- saveProc = (ep->proc) ? ep->proc: 0;
-
- memset(&proc, 0, sizeof(EjsProc));
- proc.procName = mprStrdup(id);
- proc.fn = ep->currentProperty;
- proc.args = mprCreateArray();
- ep->proc = &proc;
-
- mprDestroyVar(&ep->result);
-
- saveObj = ep->currentObj;
- if (ejsParse(ep, EJS_STATE_ARG_LIST, flags) != EJS_STATE_ARG_LIST_DONE) {
- freeProc(&proc);
- ep->proc = saveProc;
- return -1;
- }
- ep->currentObj = saveObj;
-
- /*
- * Evaluate the function if required
- */
- if (flags & EJS_FLAGS_EXE) {
- if (evalFunction(ep, ep->currentObj, flags) < 0) {
- freeProc(&proc);
- ep->proc = saveProc;
- return -1;
- }
- }
-
- freeProc(&proc);
- ep->proc = saveProc;
-
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- return -1;
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * 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, char **fullName,
- int *fullNameLen, int *done)
-{
- int tid;
-
- mprFree(*id);
- *id = mprStrdup(ep->token);
-#if BLD_DEBUG
- *fullNameLen = mprReallocStrcat(fullName, MPR_MAX_VAR, *fullNameLen,
- 0, *id, NULL);
-#endif
- if (ep->currentObj == 0) {
- ep->currentObj = ejsFindObj(ep, state, *id, flags);
- }
-
- /*
- * Find the referenced variable and store it in currentProperty.
- */
- ep->currentProperty = ejsFindProperty(ep, state, ep->currentObj,
- *id, flags);
- updateResult(ep, state, flags, ep->currentProperty);
-
-#if BLD_DEBUG
- if (ep->currentProperty && (ep->currentProperty->name == 0 ||
- ep->currentProperty->name[0] == '\0')) {
- mprSetVarName(ep->currentProperty, *id);
- }
-#endif
-
- tid = ejsLexGetToken(ep, state);
- if (tid == EJS_TOK_LPAREN) {
- if (ep->currentProperty == 0 && (flags & EJS_FLAGS_EXE)) {
- ejsError(ep, "Function name not defined \"%s\"\n", *id);
- return -1;
- }
- ejsLexPutbackToken(ep, EJS_TOK_FUNCTION_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;
- }
-
- /*
- * 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, "Variable already defined \"%s\"\n", *id);
- return -1;
- }
-#endif
- /*
- * Create or overwrite if it already exists
- */
- mprSetPropertyValue(ep->currentObj, *id,
- mprCreateUndefinedVar());
- ep->currentProperty = 0;
- mprDestroyVar(&ep->result);
-
- } else if (flags & EJS_FLAGS_FOREACH) {
- if (ep->currentProperty == 0) {
- ep->currentProperty =
- mprCreatePropertyValue(ep->currentObj, *id,
- mprCreateUndefinedVar());
- }
-
- } else {
- if (ep->currentProperty == 0) {
- if (ep->currentObj == ep->global ||
- ep->currentObj == ep->local) {
- ejsError(ep, "Undefined variable \"%s\"\n", *id);
- return -1;
- }
- ep->currentProperty = mprCreatePropertyValue(ep->currentObj,
- *id, mprCreateUndefinedVar());
- }
- }
- }
- ejsLexPutbackToken(ep, tid, ep->token);
- if (tid == EJS_TOK_RBRACKET || tid == EJS_TOK_COMMA ||
- tid == EJS_TOK_IN) {
- *done = 1;
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse an "if" statement
- */
-
-static int parseIf(Ejs *ep, int state, int flags, int *done)
-{
- bool ifResult;
- int thenFlags, elseFlags, tid;
-
- if (state != EJS_STATE_STMT) {
- return -1;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_LPAREN) {
- return -1;
- }
-
- /*
- * Evaluate the entire condition list "(condition)"
- */
- if (ejsParse(ep, EJS_STATE_COND, flags) != EJS_STATE_COND_DONE) {
- return -1;
- }
- if (ejsLexGetToken(ep, state) != EJS_TOK_RPAREN) {
- return -1;
- }
-
- /*
- * This is the "then" case. We need to always parse both cases and
- * execute only the relevant case.
- */
- ifResult = mprVarToBool(&ep->result);
- if (ifResult) {
- thenFlags = flags;
- elseFlags = flags & ~EJS_FLAGS_EXE;
- } else {
- thenFlags = flags & ~EJS_FLAGS_EXE;
- elseFlags = flags;
- }
-
- /*
- * Process the "then" case.
- */
- switch (ejsParse(ep, EJS_STATE_STMT, thenFlags)) {
- case EJS_STATE_RET:
- state = EJS_STATE_RET;
- return state;
- case EJS_STATE_STMT_DONE:
- break;
- default:
- return -1;
- }
-
- /*
- * Check to see if there is an "else" case
- */
- removeNewlines(ep, state);
- tid = ejsLexGetToken(ep, state);
- if (tid != EJS_TOK_ELSE) {
- ejsLexPutbackToken(ep, tid, ep->token);
- *done = 1;
- return state;
- }
-
- /*
- * Process the "else" case.
- */
- switch (ejsParse(ep, EJS_STATE_STMT, elseFlags)) {
- case EJS_STATE_RET:
- state = EJS_STATE_RET;
- return state;
- case EJS_STATE_STMT_DONE:
- break;
- default:
- return -1;
- }
- *done = 1;
- return state;
-}
-
-/******************************************************************************/
-/*
- * Parse an "++" or "--" statement
- */
-
-static int parseInc(Ejs *ep, int state, int flags)
-{
- MprVar one;
-
- if (! (flags & EJS_FLAGS_EXE)) {
- return state;
- }
-
- if (ep->currentProperty == 0) {
- ejsError(ep, "Undefined variable \"%s\"\n", ep->token);
- return -1;
- }
- one = mprCreateIntegerVar(1);
- if (evalExpr(ep, ep->currentProperty, (int) *ep->token,
- &one) < 0) {
- return -1;
- }
- if (mprWriteProperty(ep->currentProperty, &ep->result) < 0) {
- ejsError(ep, "Can't write to variable\n");
- return -1;
- }
- return state;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a condition. Implements &&, ||, !. Returns with a boolean result
- * in ep->result. Returns -1 on errors, zero if successful.
- */
-
-static int evalCond(Ejs *ep, MprVar *lhs, int rel, MprVar *rhs)
-{
- bool l, r, lval;
-
- mprAssert(rel > 0);
-
- l = mprVarToBool(lhs);
- r = mprVarToBool(rhs);
-
- switch (rel) {
- case EJS_COND_AND:
- lval = l && r;
- break;
- case EJS_COND_OR:
- lval = l || r;
- break;
- default:
- ejsError(ep, "Bad operator %d", rel);
- return -1;
- }
-
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval), 0);
- return 0;
-}
-
-
-/*
- return true if this string is a valid number
-*/
-static int string_is_number(const char *s)
-{
- char *endptr = NULL;
- if (s == NULL || *s == 0) {
- return 0;
- }
- strtod(s, &endptr);
- 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, MprVar *lhs, int rel, MprVar *rhs)
-{
- char *str;
- MprNum lval, num;
- 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.
- *
- * First convert objects to comparable types. The "===" operator will
- * test the sameness of object references. Here, we coerce to comparable
- * types first.
- */
- if (lhs->type == MPR_TYPE_OBJECT) {
- if (ejsRunFunction(ep->eid, lhs, "toValue", 0) == 0) {
- mprCopyVar(lhs, &ep->result, MPR_SHALLOW_COPY);
- } else {
- if (ejsRunFunction(ep->eid, lhs, "toString", 0) == 0) {
- mprCopyVar(lhs, &ep->result, MPR_SHALLOW_COPY);
- }
- }
- /* Nothing more can be done */
- }
-
- if (rhs->type == MPR_TYPE_OBJECT) {
- if (ejsRunFunction(ep->eid, rhs, "toValue", 0) == 0) {
- mprCopyVar(rhs, &ep->result, MPR_SHALLOW_COPY);
- } else {
- if (ejsRunFunction(ep->eid, rhs, "toString", 0) == 0) {
- mprCopyVar(rhs, &ep->result, MPR_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 == MPR_TYPE_UNDEFINED || rhs->type == MPR_TYPE_UNDEFINED) {
- return evalBoolExpr(ep,
- lhs->type == MPR_TYPE_UNDEFINED,
- rel,
- rhs->type == MPR_TYPE_UNDEFINED);
- }
-
- if (lhs->type == MPR_TYPE_NULL || rhs->type == MPR_TYPE_NULL) {
- return evalBoolExpr(ep,
- lhs->type == MPR_TYPE_NULL,
- rel,
- rhs->type == MPR_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 == MPR_TYPE_BOOL && rhs->type == MPR_TYPE_BOOL &&
- (rel != EJS_EXPR_EQ && rel != EJS_EXPR_NOTEQ &&
- rel != EJS_EXPR_BOOL_COMP)) {
- num = mprVarToNumber(lhs);
- mprDestroyVar(lhs);
- *lhs = mprCreateNumberVar(num);
- }
-
- /*
- * 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 == MPR_TYPE_STRING) {
- if (string_is_number(lhs->string)) {
- num = mprVarToNumber(lhs);
- lhs->allocatedVar = 0;
- mprDestroyVar(lhs);
- *lhs = mprCreateNumberVar(num);
- /* Examine further below */
-
- } else {
- /*
- * Convert the RHS to a string
- */
- mprVarToString(&str, MPR_MAX_STRING, 0, rhs);
- rhs->allocatedVar = 0;
- mprDestroyVar(rhs);
- *rhs = mprCreateStringVar(str, 1);
- mprFree(str);
- }
-
-#if BLD_FEATURE_FLOATING_POINT
- } else if (lhs->type == MPR_TYPE_FLOAT) {
- /*
- * Convert rhs to floating
- */
- double f = mprVarToFloat(rhs);
- mprDestroyVar(rhs);
- *rhs = mprCreateFloatVar(f);
-
-#endif
-#if BLD_FEATURE_INT64
- } else if (lhs->type == MPR_TYPE_INT64) {
- /*
- * Convert the rhs to 64 bit
- */
- int64 n = mprVarToInteger64(rhs);
- mprDestroyVar(rhs);
- *rhs = mprCreateInteger64Var(n);
-#endif
- } else if (lhs->type == MPR_TYPE_BOOL || lhs->type == MPR_TYPE_INT) {
-
- if (rhs->type == MPR_TYPE_STRING) {
- /*
- * Convert to lhs to a string
- */
- mprVarToString(&str, MPR_MAX_STRING, 0, lhs);
- mprDestroyVar(lhs);
- *lhs = mprCreateStringVar(str, 1);
- mprFree(str);
-
-#if BLD_FEATURE_FLOATING_POINT
- } else if (rhs->type == MPR_TYPE_FLOAT) {
- /*
- * Convert lhs to floating
- */
- double f = mprVarToFloat(lhs);
- mprDestroyVar(lhs);
- *lhs = mprCreateFloatVar(f);
-#endif
-
- } else {
- /*
- * Convert both operands to numbers
- */
- num = mprVarToNumber(lhs);
- mprDestroyVar(lhs);
- *lhs = mprCreateNumberVar(num);
-
- num = mprVarToNumber(rhs);
- mprDestroyVar(rhs);
- *rhs = mprCreateNumberVar(num);
- }
- }
- }
-
- /*
- * 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 == MPR_TYPE_UNDEFINED || lhs->type == MPR_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 = ! mprVarToBool(rhs);
- break;
- default:
- lval = 0;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar((bool) lval), 0);
- return 0;
- }
-
- /*
- * Types are the same here
- */
- switch (lhs->type) {
- default:
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- /* Should be handled above */
- mprAssert(0);
- return 0;
-
- case MPR_TYPE_STRING_CFUNCTION:
- case MPR_TYPE_CFUNCTION:
- case MPR_TYPE_FUNCTION:
- case MPR_TYPE_OBJECT:
- mprCopyVarValue(&ep->result, mprCreateBoolVar(0), 0);
- return 0;
-
- case MPR_TYPE_PTR:
- rc = evalPtrExpr(ep, lhs->ptr, rel, rhs->ptr);
- break;
-
- case MPR_TYPE_BOOL:
- rc = evalBoolExpr(ep, lhs->boolean, rel, rhs->boolean);
- break;
-
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
- rc = evalFloatExpr(ep, lhs->floating, rel, rhs->floating);
- break;
-#endif
-
- case MPR_TYPE_INT:
- rc = evalNumericExpr(ep, (MprNum) lhs->integer, rel,
- (MprNum) rhs->integer);
- break;
-
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
- rc = evalNumericExpr(ep, (MprNum) lhs->integer64, rel,
- (MprNum) rhs->integer64);
- break;
-#endif
-
- case MPR_TYPE_STRING:
- rc = evalStringExpr(ep, lhs, rel, rhs);
- }
- return rc;
-}
-
-/******************************************************************************/
-#if BLD_FEATURE_FLOATING_POINT
-/*
- * Expressions with floating operands
- */
-
-static int evalFloatExpr(Ejs *ep, double l, int rel, double r)
-{
- double lval;
- bool 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, "Bad operator %d", rel);
- return -1;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval != 0), 0);
-
- } else {
- mprCopyVarValue(&ep->result, mprCreateFloatVar(lval), 0);
- }
- return 0;
-}
-
-#endif /* BLD_FEATURE_FLOATING_POINT */
-/******************************************************************************/
-/*
- * Expressions with boolean operands
- */
-
-static int evalBoolExpr(Ejs *ep, bool l, int rel, bool r)
-{
- bool 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, "Bad operator %d", rel);
- return -1;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval), 0);
- return 0;
-}
-
-static int evalPtrExpr(Ejs *ep, void *l, int rel, void *r)
-{
- bool 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 == NULL) ? 1 : 0;
- break;
- default:
- ejsError(ep, "Bad operator %d", rel);
- return -1;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval), 0);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Expressions with numeric operands
- */
-
-static int evalNumericExpr(Ejs *ep, MprNum l, int rel, MprNum r)
-{
- MprNum lval;
- bool 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, "Divide by zero");
- return -1;
- }
- break;
- case EJS_EXPR_MOD:
- if (r != 0) {
- lval = l % r;
- } else {
- ejsError(ep, "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, "Bad operator %d", rel);
- return -1;
- }
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval != 0), 0);
-
- } else {
- mprCopyVarValue(&ep->result, mprCreateNumberVar(lval), 0);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Expressions with string operands
- */
-
-static int evalStringExpr(Ejs *ep, MprVar *lhs, int rel, MprVar *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.
- */
- mprDestroyVar(&ep->result);
- appendValue(&ep->result, lhs);
- appendValue(&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:
- ejsError(ep, "Bad operator");
- return -1;
- }
-
- mprCopyVarValue(&ep->result, mprCreateBoolVar(lval), 0);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a function. obj is set to the current object if a function is being
- * run.
- */
-
-static int evalFunction(Ejs *ep, MprVar *obj, int flags)
-{
- EjsProc *proc;
- MprVar arguments, callee, thisObject, *prototype, **argValues;
- MprArray *formalArgs, *actualArgs;
- char buf[16], **argNames, **argBuf;
- int i, rc, fid;
-
- mprAssert(ep);
- mprAssert(ejsPtr(ep->eid));
-
- rc = -1;
- proc = ep->proc;
- prototype = proc->fn;
- actualArgs = proc->args;
- argValues = (MprVar**) actualArgs->handles;
-
- /*
- * Create a new variable stack frame. ie. new local variables.
- */
- fid = ejsOpenBlock(ep->eid);
-
- if (flags & EJS_FLAGS_NEW) {
- /*
- * Create a new bare object and pass it into the constructor as the
- * "this" local variable.
- */
- thisObject = ejsCreateObj("this", EJS_OBJ_HASH_SIZE);
- mprCreatePropertyValue(ep->local, "this", thisObject);
-
- } else if (obj) {
- mprCreateProperty(ep->local, "this", obj);
- }
-
- switch (prototype->type) {
- default:
- mprAssert(0);
- break;
-
- case MPR_TYPE_STRING_CFUNCTION:
- if (actualArgs->used > 0) {
- argBuf = mprMalloc((1+actualArgs->used) * sizeof(char*));
- for (i = 0; i < actualArgs->used; i++) {
- mprVarToString(&argBuf[i], MPR_MAX_STRING, 0, argValues[i]);
- }
- argBuf[i] = NULL;
- } else {
- argBuf = 0;
- }
-
- /*
- * Call the function depending on the various handle flags
- */
- ep->thisPtr = prototype->cFunctionWithStrings.thisPtr;
- if (prototype->flags & MPR_VAR_ALT_HANDLE) {
- rc = ((EjsAltStringCFunction) prototype->cFunctionWithStrings.fn)
- (ep->eid, ep->altHandle, actualArgs->used, argBuf);
- } else if (prototype->flags & MPR_VAR_SCRIPT_HANDLE) {
- rc = (prototype->cFunctionWithStrings.fn)(ep->eid,
- actualArgs->used, argBuf);
- } else {
- rc = (prototype->cFunctionWithStrings.fn)(ep->primaryHandle,
- actualArgs->used, argBuf);
- }
-
- if (actualArgs->used > 0) {
- for (i = 0; i < actualArgs->used; i++) {
- mprFree(argBuf[i]);
- }
- mprFree(argBuf);
- }
- ep->thisPtr = 0;
- break;
-
- case MPR_TYPE_CFUNCTION:
- /*
- * Call the function depending on the various handle flags
- */
- ep->thisPtr = prototype->cFunction.thisPtr;
- if (prototype->flags & MPR_VAR_ALT_HANDLE) {
- rc = ((EjsAltCFunction) prototype->cFunction.fn)
- (ep->eid, ep->altHandle, actualArgs->used, argValues);
- } else if (prototype->flags & MPR_VAR_SCRIPT_HANDLE) {
- rc = (prototype->cFunction.fn)(ep->eid, actualArgs->used,
- argValues);
- } else {
- rc = (prototype->cFunction.fn)(ep->primaryHandle,
- actualArgs->used, argValues);
- }
- ep->thisPtr = 0;
- break;
-
- case MPR_TYPE_FUNCTION:
-
- formalArgs = prototype->function.args;
- argNames = (char**) formalArgs->handles;
-
- if (formalArgs->used > actualArgs->used) {
- ejsError(ep, "Bad number of args. Should be %d",
- formalArgs->used);
- return -1;
- }
-
- /*
- * Create the arguments and callee variables
- */
- arguments = ejsCreateObj("arguments", EJS_SMALL_OBJ_HASH_SIZE);
- callee = ejsCreateObj("callee", EJS_SMALL_OBJ_HASH_SIZE);
-
- /*
- * Overwrite the length property
- */
- mprCreatePropertyValue(&arguments, "length",
- mprCreateIntegerVar(actualArgs->used));
- mprCreatePropertyValue(&callee, "length",
- mprCreateIntegerVar(formalArgs->used));
-
- /*
- * Define all the agruments to be set to the actual parameters
- */
- for (i = 0; i < formalArgs->used; i++) {
- mprCreateProperty(ep->local, argNames[i], argValues[i]);
- }
- for (i = 0; i < actualArgs->used; i++) {
- mprItoa(i, buf, sizeof(buf));
- mprCreateProperty(&arguments, buf, argValues[i]);
- }
-
- mprCreateProperty(&arguments, "callee", &callee);
- mprCreateProperty(ep->local, "arguments", &arguments);
-
- /*
- * Can destroy our variables here as they are now referenced via
- * "local"
- */
- mprDestroyVar(&callee);
- mprDestroyVar(&arguments);
-
- /*
- * Actually run the function
- */
- rc = ejsEvalScript(ep->eid, prototype->function.body, 0, 0);
- break;
- }
-
- ejsCloseBlock(ep->eid, fid);
-
- /*
- * New statements return the newly created object as the result of the
- * command
- */
- if (flags & EJS_FLAGS_NEW) {
- mprDestroyVar(&ep->result);
- /*
- * Don't copy, we want to assign the actual object into result.
- * (mprCopyVar would inc the refCount to 2).
- */
- ep->result = thisObject;
- }
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Run a function
- */
-
-int ejsRunFunction(int eid, MprVar *obj, const char *functionName,
- MprArray *args)
-{
- EjsProc proc, *saveProc;
- Ejs *ep;
- int rc;
-
- mprAssert(obj);
- mprAssert(functionName && *functionName);
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return MPR_ERR_NOT_FOUND;
- }
- saveProc = ep->proc;
- ep->proc = &proc;
-
- memset(&proc, 0, sizeof(EjsProc));
- mprDestroyVar(&ep->result);
-
- proc.fn = mprGetProperty(obj, functionName, 0);
- if (proc.fn == 0 || proc.fn->type == MPR_TYPE_UNDEFINED) {
- ep->proc = saveProc;
- return MPR_ERR_NOT_FOUND;
- }
- proc.procName = mprStrdup(functionName);
- if (args == 0) {
- proc.args = mprCreateArray();
- rc = evalFunction(ep, obj, 0);
- } else {
- proc.args = args;
- rc = evalFunction(ep, obj, 0);
- proc.args = 0;
- }
-
- freeProc(&proc);
- ep->proc = saveProc;
-
- return rc;
-}
-
-/******************************************************************************/
-/*
- * Find which object contains the property given the current context.
- * Only used for top level properties.
- */
-
-MprVar *ejsFindObj(Ejs *ep, int state, const char *property, int flags)
-{
- MprVar *obj;
-
- mprAssert(ep);
- mprAssert(property && *property);
-
- 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 look global */
- if (mprGetProperty(ep->local, property, 0)) {
- obj = ep->local;
- } else {
- obj = ep->global;
- }
- }
- 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 function
- * names only. Returns the property or NULL.
- */
-
-MprVar *ejsFindProperty(Ejs *ep, int state, MprVar *obj, char *property,
- int flags)
-{
- MprVar *vp;
-
- mprAssert(ep);
- if (flags & EJS_FLAGS_EXE) {
- mprAssert(property && *property);
- }
-
- if (obj != 0) {
-#if FUTURE && MB
- op = obj;
- do {
- vp = mprGetProperty(op, property, 0);
- if (vp != 0) {
- if (op != obj && mprVarIsFunction(vp->type)) {
- }
- break;
- }
- op = op->baseObj;
- } while (op);
-#endif
- vp = mprGetProperty(obj, property, 0);
-
- } else {
- if (state == EJS_STATE_DEC) {
- vp = mprGetProperty(ep->local, property, 0);
-
- } else {
- /* Look local first, then global */
- vp = mprGetProperty(ep->local, property, 0);
- if (vp == NULL) {
- vp = mprGetProperty(ep->global, property, 0);
- }
- }
- }
- return vp;
-}
-
-/******************************************************************************/
-/*
- * Update result
- */
-
-static void updateResult(Ejs *ep, int state, int flags, MprVar *vp)
-{
- if (flags & EJS_FLAGS_EXE && state != EJS_STATE_DEC) {
- mprDestroyVar(&ep->result);
- if (vp) {
- mprCopyProperty(&ep->result, vp, MPR_SHALLOW_COPY);
- }
- }
-}
-
-/******************************************************************************/
-/*
- * Append to the pointer value
- */
-
-static void appendValue(MprVar *dest, MprVar *src)
-{
- char *value, *oldBuf, *buf;
- int len, oldLen;
-
- mprAssert(dest);
-
- mprVarToString(&value, MPR_MAX_STRING, 0, src);
-
- if (mprVarIsValid(dest)) {
- len = strlen(value);
- oldBuf = dest->string;
- oldLen = strlen(oldBuf);
- buf = mprRealloc(oldBuf, (len + oldLen + 1) * sizeof(char));
- dest->string = buf;
- strcpy(&buf[oldLen], value);
-
- } else {
- *dest = mprCreateStringVar(value, 1);
- }
- mprFree(value);
-}
-
-/******************************************************************************/
-/*
- * Exit with status
- */
-
-void ejsSetExitStatus(int eid, int status)
-{
- Ejs *ep;
-
- if ((ep = ejsPtr(eid)) == NULL) {
- mprAssert(ep);
- return;
- }
- ep->exitStatus = status;
- ep->flags |= EJS_FLAGS_EXIT;
-}
-
-/******************************************************************************/
-/*
- * Free an argument list
- */
-
-static void freeProc(EjsProc *proc)
-{
- MprVar **argValues;
- int i;
-
- if (proc->args) {
- argValues = (MprVar**) proc->args->handles;
-
- for (i = 0; i < proc->args->max; i++) {
- if (argValues[i]) {
- mprDestroyVar(argValues[i]);
- mprFree(argValues[i]);
- mprRemoveFromArray(proc->args, i);
- }
- }
-
- mprDestroyArray(proc->args);
- }
-
- if (proc->procName) {
- mprFree(proc->procName);
- proc->procName = NULL;
- }
-}
-
-/******************************************************************************/
-/*
- * This function 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);
-}
-
-/******************************************************************************/
-
-#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/ejsProcs.c b/source4/lib/appweb/ejs/ejsProcs.c
deleted file mode 100644
index 43fff4a40b..0000000000
--- a/source4/lib/appweb/ejs/ejsProcs.c
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * @file ejsProc.c
- * @brief EJS support functions
- */
-/********************************* Copyright **********************************/
-/*
- * @copy default.g
- *
- * Copyright (c) Mbedthis Software LLC, 2003-2005. All Rights Reserved.
- * Portions Copyright (c) GoAhead Software, 1995-2000. All Rights Reserved.
- *
- * This software is distributed under commercial and open source licenses.
- * You may use the GPL open source license described below or you may acquire
- * a commercial license from Mbedthis Software. You agree to be fully bound
- * by the terms of either license. Consult the LICENSE.TXT distributed with
- * this software for full details.
- *
- * This software is open source; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See the GNU General Public License for more
- * details at: http://www.mbedthis.com/downloads/gplLicense.html
- *
- * This program is distributed WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * This GPL license does NOT permit incorporating this software into
- * proprietary programs. If you are unable to comply with the GPL, you must
- * acquire a commercial license to use this software. Commercial licenses
- * for this software and support services are available from Mbedthis
- * Software at http://www.mbedthis.com
- *
- * @end
- */
-/********************************** Includes **********************************/
-
-#include "ejsInternal.h"
-
-#if BLD_FEATURE_EJS
-
-/****************************** Forward Declarations **************************/
-/*
- * Object constructors
- */
-static int objectConsProc(EjsHandle eid, int argc, MprVar **argv);
-static int arrayConsProc(EjsHandle eid, int argc, MprVar **argv);
-static int booleanConsProc(EjsHandle eid, int argc, MprVar **agv);
-static int numberConsProc(EjsHandle eid, int argc, MprVar **argv);
-static int stringConsProc(EjsHandle eid, int argc, MprVar **argv);
-
-/*
- * Core functions
- */
-static int toStringProc(EjsHandle eid, int argc, MprVar **argv);
-static int valueOfProc(EjsHandle eid, int argc, MprVar **argv);
-
-/*
- * Triggers
- */
-static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op,
- MprProperties *parentProperties, MprVar *prop, MprVar *newValue,
- int copyRef);
-
-/******************************************************************************/
-/*
- * Routine to create the base common to all object types
- */
-
-MprVar ejsCreateObj(const char *name, int hashSize)
-{
- MprVar o;
-
- o = mprCreateObjVar(name, hashSize);
- if (o.type == MPR_TYPE_UNDEFINED) {
- mprAssert(0);
- return o;
- }
-
- mprCreatePropertyValue(&o, "toString",
- mprCreateCFunctionVar(toStringProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(&o, "valueOf",
- mprCreateCFunctionVar(valueOfProc, 0, MPR_VAR_SCRIPT_HANDLE));
- return o;
-}
-
-/******************************************************************************/
-/*
- * Routine to destroy a variable
- */
-
-bool ejsDestroyVar(MprVar *obj)
-{
- return mprDestroyVar(obj);
-}
-
-/******************************************************************************/
-/*
- * Routine to create the base array type
- */
-
-MprVar ejsCreateArray(const char *name, int size)
-{
- MprVar obj, *lp, undef;
- char idx[16];
- int i;
-
- /* Sanity limit for size of hash table */
-
- obj = ejsCreateObj(name, max(size, 503));
- if (obj.type == MPR_TYPE_UNDEFINED) {
- mprAssert(0);
- return obj;
- }
-
- undef = mprCreateUndefinedVar();
- for (i = 0; i < size; i++) {
- mprItoa(i, idx, sizeof(idx));
- mprCreateProperty(&obj, idx, &undef);
- }
-
- lp = mprCreatePropertyValue(&obj, "length", mprCreateIntegerVar(size));
- mprAssert(lp);
-
- mprSetVarReadonly(lp, 1);
- mprAddVarTrigger(lp, lengthTrigger);
-
- return obj;
-}
-
-/******************************************************************************/
-/******************************** Constructors ********************************/
-/******************************************************************************/
-/*
- * Object constructor. Nothing really done here. For future expansion.
- */
-
-static int objectConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
-#if XX_UNUSED_XX
- MprVar *obj;
- Ejs *ep;
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
-
- obj = mprGetProperty(ep->local, "this", 0);
- mprAssert(obj);
-#endif
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Array constructor
- */
-
-static int arrayConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *obj, *lp, undef;
- Ejs *ep;
- char idx[16];
- int i, max;
-
- objectConsProc(eid, argc, argv);
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
- obj = mprGetProperty(ep->local, "this", 0);
- mprAssert(obj);
-
-
- if (argc == 1 && mprVarIsNumber(argv[0]->type)) {
- /*
- * x = new Array(size);
- */
- undef = mprCreateUndefinedVar();
- max = (int) mprVarToInteger(argv[0]);
- for (i = 0; i < max; i++) {
- mprItoa(i, idx, sizeof(idx));
- mprCreateProperty(obj, idx, &undef);
- }
- } else {
- /*
- * x = new Array(element0, element1, ..., elementN):
- */
- max = argc;
- for (i = 0; i < max; i++) {
- mprItoa(i, idx, sizeof(idx));
- mprCreateProperty(obj, idx, argv[i]);
- }
- }
-
- lp = mprCreatePropertyValue(obj, "length", mprCreateIntegerVar(max));
- mprAssert(lp);
-
- mprSetVarReadonly(lp, 1);
- mprAddVarTrigger(lp, lengthTrigger);
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Boolean constructor
- */
-
-static int booleanConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- objectConsProc(eid, argc, argv);
- return 0;
-}
-
-/******************************************************************************/
-#if FUTURE
-/*
- * Date constructor
- */
-
-static int dateConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- objectConsProc(eid, argc, argv);
- return 0;
-}
-
-#endif
-/******************************************************************************/
-/*
- * Number constructor
- */
-
-static int numberConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- objectConsProc(eid, argc, argv);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * String constructor
- */
-
-static int stringConsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- objectConsProc(eid, argc, argv);
- return 0;
-}
-
-/******************************************************************************/
-/********************************** Functions *********************************/
-/******************************************************************************/
-
-static int toStringProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *obj;
- Ejs *ep;
- char *buf;
- int radix;
-
- if (argc == 0) {
- radix = 10;
-
- } else if (argc == 1) {
- radix = (int) mprVarToInteger(argv[0]);
-
- } else {
- mprAssert(0);
- return -1;
- }
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
-
- obj = mprGetProperty(ep->local, "this", 0);
- mprAssert(obj);
-
- mprVarToString(&buf, MPR_MAX_STRING, 0, obj);
- mprCopyVarValue(&ep->result, mprCreateStringVar(buf, 0), MPR_SHALLOW_COPY);
- mprFree(buf);
-
- return 0;
-}
-
-/******************************************************************************/
-
-static int valueOfProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *obj;
- Ejs *ep;
-
- if (argc != 0) {
- mprAssert(0);
- return -1;
- }
-
- if((ep = ejsPtr(eid)) == NULL) {
- return -1;
- }
-
- obj = mprGetProperty(ep->local, "this", 0);
- mprAssert(obj);
-
- switch (obj->type) {
- default:
- case MPR_TYPE_UNDEFINED:
- case MPR_TYPE_NULL:
- case MPR_TYPE_CFUNCTION:
- case MPR_TYPE_OBJECT:
- case MPR_TYPE_FUNCTION:
- case MPR_TYPE_STRING_CFUNCTION:
- case MPR_TYPE_PTR:
- mprCopyVar(&ep->result, obj, MPR_SHALLOW_COPY);
- break;
-
- case MPR_TYPE_STRING:
- mprCopyVarValue(&ep->result, mprCreateIntegerVar(atoi(obj->string)), 0);
- break;
-
- case MPR_TYPE_BOOL:
- case MPR_TYPE_INT:
-#if BLD_FEATURE_INT64
- case MPR_TYPE_INT64:
-#endif
-#if BLD_FEATURE_FLOATING_POINT
- case MPR_TYPE_FLOAT:
-#endif
- mprCopyVar(&ep->result, obj, 0);
- break;
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Var access trigger on the Array.length property. Return the count of
- * enumerable properties (don't count functions).
- */
-
-static MprVarTriggerStatus lengthTrigger(MprVarTriggerOp op,
- MprProperties *parentProperties, MprVar *prop, MprVar *newValue,
- int copyRef)
-{
- switch (op) {
- case MPR_VAR_READ:
- /*
- * Subtract one for the length property
- * FUTURE -- need an API to access parentProperties
- * FUTURE -- contradiction to be read-only yet allow USE_NEW_VALUE.
- * API needs finer control.
- */
- *newValue = mprCreateIntegerVar(parentProperties->numDataItems - 1);
- return MPR_TRIGGER_USE_NEW_VALUE;
-
- case MPR_VAR_WRITE:
- return MPR_TRIGGER_ABORT;
-
- case MPR_VAR_CREATE_PROPERTY:
- case MPR_VAR_DELETE_PROPERTY:
- case MPR_VAR_DELETE:
- default:
- break;
- }
- return MPR_TRIGGER_PROCEED;
-}
-
-/******************************************************************************/
-/**************************** Extension Functions *****************************/
-/******************************************************************************/
-/*
- * Assert
- */
-
-static int assertProc(EjsHandle eid, int argc, MprVar **argv)
-{
- bool b;
-
- if (argc < 1) {
- ejsSetErrorMsg(eid, "usage: assert(condition)\n");
- return -1;
- }
- b = mprVarToBool(argv[0]);
- if (b == 0) {
- ejsSetErrorMsg(eid, "Assertion failure\n");
- return -1;
- }
- ejsSetReturnValue(eid, mprCreateBoolVar(b));
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Exit
- */
-
-static int exitProc(EjsHandle eid, int argc, MprVar **argv)
-{
- int status;
-
- if (argc < 1) {
- ejsSetErrorMsg(eid, "usage: exit(status)\n");
- return -1;
- }
- status = (int) mprVarToInteger(argv[0]);
- ejsSetExitStatus(eid, status);
-
- ejsSetReturnValue(eid, mprCreateStringVar("", 0));
- return 0;
-}
-
-/******************************************************************************/
-
-static void printVar(MprVar *vp, int recurseCount, int indent)
-{
- MprVar *np;
- char *buf;
- int i;
-
- if (recurseCount > 5) {
- write(1, "Skipping - recursion too deep\n", 29);
- return;
- }
-
- for (i = 0; i < indent; i++) {
- write(1, " ", 2);
- }
-
- if (vp->type == MPR_TYPE_OBJECT) {
- if (vp->name) {
- write(1, vp->name, strlen(vp->name));
- } else {
- write(1, "unknown", 7);
- }
- write(1, ": {\n", 4);
- np = mprGetFirstProperty(vp, MPR_ENUM_DATA);
- while (np) {
- if (strcmp(np->name, "local") == 0 ||
- strcmp(np->name, "global") == 0 ||
- strcmp(np->name, "this") == 0) {
- np = mprGetNextProperty(vp, np, MPR_ENUM_DATA);
- continue;
- }
- printVar(np, recurseCount + 1, indent + 1);
- np = mprGetNextProperty(vp, np, MPR_ENUM_DATA);
- if (np) {
- write(1, ",\n", 2);
- }
- }
- write(1, "\n", 1);
- for (i = 0; i < indent; i++) {
- write(1, " ", 2);
- }
- write(1, "}", 1);
-
- } else {
- if (vp->name) {
- write(1, vp->name, strlen(vp->name));
- } else {
- write(1, "unknown", 7);
- }
- write(1, ": ", 2);
-
- /* FUTURE -- other types ? */
- mprVarToString(&buf, MPR_MAX_STRING, 0, vp);
- if (vp->type == MPR_TYPE_STRING) {
- write(1, "\"", 1);
- }
- write(1, buf, strlen(buf));
- if (vp->type == MPR_TYPE_STRING) {
- write(1, "\"", 1);
- }
- mprFree(buf);
- }
-}
-
-/******************************************************************************/
-/*
- * Print the args to stdout
- */
-
-static int printVarsProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *vp;
- char *buf;
- int i;
-
- for (i = 0; i < argc; i++) {
- vp = argv[i];
- switch (vp->type) {
- case MPR_TYPE_OBJECT:
- printVar(vp, 0, 0);
- break;
- default:
- mprVarToString(&buf, MPR_MAX_STRING, 0, vp);
- write(1, buf, strlen(buf));
- mprFree(buf);
- break;
- }
- }
- write(1, "\n", 1);
-
- ejsSetReturnValue(eid, mprCreateStringVar("", 0));
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Print the args to stdout
- */
-
-static int printProc(EjsHandle eid, int argc, MprVar **argv)
-{
- char *buf;
- int i;
-
- for (i = 0; i < argc; i++) {
- mprVarToString(&buf, MPR_MAX_STRING, 0, argv[i]);
- write(1, buf, strlen(buf));
- mprFree(buf);
- }
- return 0;
-}
-
-/******************************************************************************/
-/*
- * println
- */
-
-static int printlnProc(EjsHandle eid, int argc, MprVar **argv)
-{
- printProc(eid, argc, argv);
- write(1, "\n", 1);
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Trace
- */
-
-static int traceProc(EjsHandle eid, int argc, char **argv)
-{
- if (argc == 1) {
- mprLog(0, "%s", argv[0]);
-
- } else if (argc == 2) {
- mprLog(atoi(argv[0]), "%s", argv[1]);
-
- } else {
- ejsSetErrorMsg(eid, "Usage: trace([level], message)");
- return -1;
- }
- ejsSetReturnString(eid, "");
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Return the object reference count
- */
-
-static int refCountProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *vp;
- int count;
-
- vp = argv[0];
- if (vp->type == MPR_TYPE_OBJECT) {
- count = mprGetVarRefCount(vp);
- ejsSetReturnValue(eid, mprCreateIntegerVar(count));
- } else {
- ejsSetReturnValue(eid, mprCreateIntegerVar(0));
- }
-
- return 0;
-}
-
-/******************************************************************************/
-/*
- * Evaluate a sub-script. It is evaluated in the same variable scope as
- * the calling script / function.
- */
-
-static int evalScriptProc(EjsHandle eid, int argc, MprVar **argv)
-{
- MprVar *arg;
- char *emsg;
- int i;
-
- ejsSetReturnValue(eid, mprCreateUndefinedVar());
-
- for (i = 0; i < argc; i++) {
- arg = argv[i];
- if (arg->type != MPR_TYPE_STRING) {
- continue;
- }
- if (ejsEvalScript(eid, arg->string, 0, &emsg) < 0) {
- ejsSetErrorMsg(eid, "%s", emsg);
- mprFree(emsg);
- return -1;
- }
- }
- /*
- * Return with the value of the last expression
- */
- return 0;
-}
-
-/******************************************************************************/
-/******************************************************************************/
-/******************************************************************************/
-/*
- * Define the standard properties and functions inherited by all script engines.
- */
-
-int ejsDefineStandardProperties(MprVar *obj)
-{
-#if BLD_FEATURE_FLOATING_POINT
- double d = 0.0;
-
- /* FUTURE - this generates warnings on some systems. This is okay. */
-
- mprCreatePropertyValue(obj, "NaN", mprCreateFloatVar(0.0 / d));
- d = MAX_FLOAT;
- mprCreatePropertyValue(obj, "Infinity", mprCreateFloatVar(d * d));
-#endif
- mprCreatePropertyValue(obj, "null", mprCreateNullVar());
- mprCreatePropertyValue(obj, "undefined", mprCreateUndefinedVar());
- mprCreatePropertyValue(obj, "true", mprCreateBoolVar(1));
- mprCreatePropertyValue(obj, "false", mprCreateBoolVar(0));
- mprCreatePropertyValue(obj, "NULL", mprCreatePtrVar(NULL));
-
-#if BLD_FEATURE_LEGACY_API
- /*
- * DEPRECATED: 2.0.
- * So that ESP/ASP can ignore "language=javascript" statements
- */
- mprCreatePropertyValue(obj, "javascript", mprCreateIntegerVar(0));
-#endif
-
- /*
- * Extension functions
- */
- mprCreatePropertyValue(obj, "assert",
- mprCreateCFunctionVar(assertProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "eval",
- mprCreateCFunctionVar(evalScriptProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "exit",
- mprCreateCFunctionVar(exitProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "refCount",
- mprCreateCFunctionVar(refCountProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "print",
- mprCreateCFunctionVar(printProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "println",
- mprCreateCFunctionVar(printlnProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "printVars",
- mprCreateCFunctionVar(printVarsProc,0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "trace",
- mprCreateStringCFunctionVar(traceProc, 0, MPR_VAR_SCRIPT_HANDLE));
-
- /*
- * Constructors
- */
- mprCreatePropertyValue(obj, "Array",
- mprCreateCFunctionVar(arrayConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "Boolean",
- mprCreateCFunctionVar(booleanConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "Object",
- mprCreateCFunctionVar(objectConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "Number",
- mprCreateCFunctionVar(numberConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- mprCreatePropertyValue(obj, "String",
- mprCreateCFunctionVar(stringConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
-
- /* mprCreatePropertyValue(obj, "Date",
- * mprCreateCFunctionVar(dateConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- * mprCreatePropertyValue(obj, "Regexp",
- * mprCreateCFunctionVar(regexpConsProc, 0, MPR_VAR_SCRIPT_HANDLE));
- */
-
- /*
- * Can we use on var x = "string text";
- */
- return 0;
-}
-
-/******************************************************************************/
-
-#else
-void ejsProcsDummy() {}
-
-/******************************************************************************/
-#endif /* BLD_FEATURE_EJS */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim:tw=78
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */