786 lines
17 KiB
C
786 lines
17 KiB
C
|
|
/*
|
||
|
|
* @file ejsGlobal.c
|
||
|
|
* @brief EJS support methods
|
||
|
|
*/
|
||
|
|
/********************************* Copyright **********************************/
|
||
|
|
/*
|
||
|
|
* @copy default
|
||
|
|
*
|
||
|
|
* Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
|
||
|
|
* Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
|
||
|
|
*
|
||
|
|
* This software is distributed under commercial and open source licenses.
|
||
|
|
* You may use the GPL open source license described below or you may acquire
|
||
|
|
* a commercial license from Mbedthis Software. You agree to be fully bound
|
||
|
|
* by the terms of either license. Consult the LICENSE.TXT distributed with
|
||
|
|
* this software for full details.
|
||
|
|
*
|
||
|
|
* This software is open source; you can redistribute it and/or modify it
|
||
|
|
* under the terms of the GNU General Public License as published by the
|
||
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||
|
|
* option) any later version. See the GNU General Public License for more
|
||
|
|
* details at: http://www.mbedthis.com/downloads/gplLicense.html
|
||
|
|
*
|
||
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the
|
||
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
|
*
|
||
|
|
* This GPL license does NOT permit incorporating this software into
|
||
|
|
* proprietary programs. If you are unable to comply with the GPL, you must
|
||
|
|
* acquire a commercial license to use this software. Commercial licenses
|
||
|
|
* for this software and support services are available from Mbedthis
|
||
|
|
* Software at http://www.mbedthis.com
|
||
|
|
*
|
||
|
|
* @end
|
||
|
|
*/
|
||
|
|
/********************************** Includes **********************************/
|
||
|
|
|
||
|
|
#include "ejs.h"
|
||
|
|
|
||
|
|
#if BLD_FEATURE_EJS
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/************************************* Code ***********************************/
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* assert(condition)
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int assertProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
int b;
|
||
|
|
|
||
|
|
if (argc < 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "usage: assert(condition)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
b = ejsVarToBoolean(argv[0]);
|
||
|
|
if (b == 0) {
|
||
|
|
ejsError(ep, EJS_ASSERT_ERROR, "Assertion failure at line %d",
|
||
|
|
ejsGetLineNumber(ep));
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
ejsWriteVarAsBoolean(ep, ep->result, b);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* breakpoint(msg)
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int breakpointProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
char *buf;
|
||
|
|
|
||
|
|
if (argc < 1) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
buf = ejsVarToString(ep, argv[0]);
|
||
|
|
if (buf) {
|
||
|
|
mprBreakpoint(0, buf);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* basename(path)
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int basenameProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
char *path;
|
||
|
|
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "usage: basename(path)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
path = ejsVarToString(ep, argv[0]);
|
||
|
|
if (path == 0) {
|
||
|
|
return MPR_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
ejsSetReturnValueToString(ep, mprGetBaseName(path));
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* stripext(path)
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int stripextProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
char *cp, *path, *stripPath;
|
||
|
|
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "usage: stripext(path)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
path = ejsVarToString(ep, argv[0]);
|
||
|
|
if (path == 0) {
|
||
|
|
return MPR_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
stripPath = mprStrdup(ep, path);
|
||
|
|
|
||
|
|
if ((cp = strrchr(stripPath, '.')) != 0) {
|
||
|
|
*cp = '\0';
|
||
|
|
}
|
||
|
|
|
||
|
|
ejsSetReturnValueToString(ep, stripPath);
|
||
|
|
|
||
|
|
mprFree(stripPath);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* dirname(path)
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int dirnameProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
char *path;
|
||
|
|
char dirname[MPR_MAX_FNAME];
|
||
|
|
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "usage: dirname(path)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
path = ejsVarToString(ep, argv[0]);
|
||
|
|
if (path == 0) {
|
||
|
|
return MPR_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
|
||
|
|
ejsSetReturnValueToString(ep,
|
||
|
|
mprGetDirName(dirname, sizeof(dirname), path));
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* trim(string) -- trim white space
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int trimProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
char *str, *buf, *cp;
|
||
|
|
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "usage: trim(string)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
str = ejsVarToString(ep, argv[0]);
|
||
|
|
if (str == 0) {
|
||
|
|
return MPR_ERR_MEMORY;
|
||
|
|
}
|
||
|
|
str = buf = mprStrdup(ep, str);
|
||
|
|
|
||
|
|
while (isspace(*str)) {
|
||
|
|
str++;
|
||
|
|
}
|
||
|
|
cp = &str[strlen(str) - 1];
|
||
|
|
while (cp >= str) {
|
||
|
|
if (isspace(*cp)) {
|
||
|
|
*cp = '\0';
|
||
|
|
} else {
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
cp--;
|
||
|
|
}
|
||
|
|
|
||
|
|
ejsSetReturnValueToString(ep, str);
|
||
|
|
|
||
|
|
mprFree(buf);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* Terminate the script
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int exitScript(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
int status;
|
||
|
|
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "usage: exit(status)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
status = (int) ejsVarToInteger(argv[0]);
|
||
|
|
ejsExit(ep, status);
|
||
|
|
|
||
|
|
ejsWriteVarAsString(ep, ep->result, "");
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* include javascript libraries.
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int includeProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv)
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
|
||
|
|
mprAssert(argv);
|
||
|
|
|
||
|
|
for (i = 0; i < argc; i++) {
|
||
|
|
if (ejsEvalFile(ep, argv[i], 0) < 0) {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* include javascript libraries at the global level
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int includeGlobalProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv)
|
||
|
|
{
|
||
|
|
int fid, i;
|
||
|
|
|
||
|
|
mprAssert(argv);
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Create a new block and set the context to be the global scope
|
||
|
|
*/
|
||
|
|
fid = ejsSetBlock(ep, ep->global);
|
||
|
|
|
||
|
|
for (i = 0; i < argc; i++) {
|
||
|
|
if (ejsEvalFile(ep, argv[i], 0) < 0) {
|
||
|
|
ejsCloseBlock(ep, fid);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ejsCloseBlock(ep, fid);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
#if BLD_DEBUG
|
||
|
|
/*
|
||
|
|
* Print variables to stdout
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int printvProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
EjsVar *vp;
|
||
|
|
char *buf;
|
||
|
|
int i;
|
||
|
|
|
||
|
|
for (i = 0; i < argc; ) {
|
||
|
|
vp = argv[i++];
|
||
|
|
|
||
|
|
/* mprPrintf(ep, "arg[%d] = ", i); */
|
||
|
|
|
||
|
|
buf = ejsVarToString(ep, vp);
|
||
|
|
|
||
|
|
if (vp->propertyName == 0 || *vp->propertyName == '\0') {
|
||
|
|
mprPrintf(ep, "%s: ", buf);
|
||
|
|
|
||
|
|
} else if (i < argc) {
|
||
|
|
mprPrintf(ep, "%s = %s, ", vp->propertyName, buf);
|
||
|
|
} else {
|
||
|
|
mprPrintf(ep, "%s = %s\n", vp->propertyName, buf);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* Print the args to stdout
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int printProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
char *buf;
|
||
|
|
int i;
|
||
|
|
|
||
|
|
for (i = 0; i < argc; i++) {
|
||
|
|
buf = ejsVarToString(ep, argv[i]);
|
||
|
|
mprPrintf(ep, "%s", buf);
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* println
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int printlnProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
printProc(ep, thisObj, argc, argv);
|
||
|
|
mprPrintf(ep, "\n");
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
#if FUTURE
|
||
|
|
/*
|
||
|
|
* sprintf
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int sprintfProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
va_list ap;
|
||
|
|
char *buf;
|
||
|
|
void **args;
|
||
|
|
int result;
|
||
|
|
|
||
|
|
if (argc <= 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "Usage: sprintf(fmt, [args ...])");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
args = mprAlloc(ep, sizeof(void*) * (argc - 1));
|
||
|
|
if (args == 0) {
|
||
|
|
mprAssert(args);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 1; i < argc; i++) {
|
||
|
|
args[i - 1] = argv[i]);
|
||
|
|
}
|
||
|
|
|
||
|
|
va_start(ap, fmt);
|
||
|
|
*buf = 0;
|
||
|
|
result = inner(0, &buf, MPR_MAX_STRING, fmt, args);
|
||
|
|
va_end(ap);
|
||
|
|
|
||
|
|
ejsSetReturnValueToString(ep, buf);
|
||
|
|
|
||
|
|
mprFree(buf);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
|
||
|
|
inner(const char *fmt, void **args)
|
||
|
|
{
|
||
|
|
va_list ap;
|
||
|
|
|
||
|
|
va_start(ap, fmt);
|
||
|
|
*buf = 0;
|
||
|
|
mprSprintfCore(ctx, &buf, maxSize, fmt, ap, MPR_PRINTF_ARGV);
|
||
|
|
va_end(ap);
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* sleep
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int sleepProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "Usage: sleep(milliseconds)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
mprSleep(ep, ejsVarToInteger(argv[0]));
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* sort properties
|
||
|
|
* FUTURE -- should have option to sort object based on a given property value
|
||
|
|
* ascending or descending
|
||
|
|
* Usage: sort(object, order = ascending, property = 0);
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int sortProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
const char *property;
|
||
|
|
int error, order;
|
||
|
|
|
||
|
|
error = 0;
|
||
|
|
property = 0;
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Default order is increasing
|
||
|
|
*/
|
||
|
|
order = 1;
|
||
|
|
|
||
|
|
if (argc < 1 || argc > 3 || !ejsVarIsObject(argv[0])) {
|
||
|
|
error++;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (argc >= 2) {
|
||
|
|
order = ejsVarToInteger(argv[1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* If property is not defined, it sorts the properties in the object
|
||
|
|
*/
|
||
|
|
if (argc == 3) {
|
||
|
|
if (! ejsVarIsString(argv[2])) {
|
||
|
|
error++;
|
||
|
|
} else {
|
||
|
|
property = argv[2]->string;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (error) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "Usage: sort(object, [order], [property])");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
ejsSortProperties(ep, argv[0], 0, property, order);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* Get a time mark
|
||
|
|
* MOB -- WARNING: this can overflow. OK on BREW, but other O/Ss it may have
|
||
|
|
* overflowed on the first call. It should be renamed.
|
||
|
|
* MOB -- replace with proper Date.
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int timeProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
MprTime now;
|
||
|
|
|
||
|
|
mprGetTime(ep, &now);
|
||
|
|
#if WIN || LINUX || SOLARIS
|
||
|
|
{
|
||
|
|
/* MOB -- poor hack */
|
||
|
|
static MprTime initial;
|
||
|
|
if (initial.sec == 0) {
|
||
|
|
initial = now;
|
||
|
|
}
|
||
|
|
now.sec -= initial.sec;
|
||
|
|
|
||
|
|
if (initial.msec > now.msec) {
|
||
|
|
now.msec = now.msec + 1000 - initial.msec;
|
||
|
|
now.sec--;
|
||
|
|
} else {
|
||
|
|
now.msec -= initial.msec;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
/* MOB -- this can overflow */
|
||
|
|
ejsSetReturnValueToInteger(ep, now.sec * 1000 + now.msec);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* MOB -- Temporary Get the date (time since Jan 6, 1980 GMT
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int dateProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
#if BREW
|
||
|
|
uint now;
|
||
|
|
|
||
|
|
now = GETTIMESECONDS();
|
||
|
|
ejsSetReturnValueToInteger(ep, now);
|
||
|
|
#endif
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* strlen(string)
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int strlenProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
char *buf;
|
||
|
|
int len;
|
||
|
|
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "Usage: strlen(var)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
len = 0;
|
||
|
|
if (! ejsVarIsString(argv[0])) {
|
||
|
|
buf = ejsVarToString(ep, argv[0]);
|
||
|
|
if (buf) {
|
||
|
|
len = strlen(buf);
|
||
|
|
}
|
||
|
|
|
||
|
|
} else {
|
||
|
|
len = argv[0]->length;
|
||
|
|
}
|
||
|
|
|
||
|
|
ejsSetReturnValueToInteger(ep, len);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* toint(num)
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int tointProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
int i;
|
||
|
|
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "Usage: toint(number)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
i = ejsVarToInteger(argv[0]);
|
||
|
|
|
||
|
|
ejsSetReturnValueToInteger(ep, i);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* string strstr(string, pat)
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int strstrProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
char *str, *pat;
|
||
|
|
char *s;
|
||
|
|
int strAlloc;
|
||
|
|
|
||
|
|
if (argc != 2) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "Usage: strstr(string, pat)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
str = ejsVarToString(ep, argv[0]);
|
||
|
|
|
||
|
|
strAlloc = ep->castAlloc;
|
||
|
|
ep->castTemp = 0;
|
||
|
|
|
||
|
|
pat = ejsVarToString(ep, argv[1]);
|
||
|
|
|
||
|
|
s = strstr(str, pat);
|
||
|
|
|
||
|
|
if (s == 0) {
|
||
|
|
ejsSetReturnValueToUndefined(ep);
|
||
|
|
} else {
|
||
|
|
ejsSetReturnValueToString(ep, s);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (strAlloc) {
|
||
|
|
mprFree(str);
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* Trace
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int traceProc(Ejs *ep, EjsVar *thisObj, int argc, char **argv)
|
||
|
|
{
|
||
|
|
if (argc == 1) {
|
||
|
|
mprLog(ep, 0, "%s", argv[0]);
|
||
|
|
|
||
|
|
} else if (argc == 2) {
|
||
|
|
mprLog(ep, atoi(argv[0]), "%s", argv[1]);
|
||
|
|
|
||
|
|
} else {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "Usage: trace([level], message)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
ejsWriteVarAsString(ep, ep->result, "");
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* Evaluate a sub-script. It is evaluated in the same variable scope as
|
||
|
|
* the calling script / method.
|
||
|
|
*/
|
||
|
|
|
||
|
|
static int evalScriptProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
EjsVar *arg;
|
||
|
|
int i;
|
||
|
|
|
||
|
|
ejsWriteVarAsUndefined(ep, ep->result);
|
||
|
|
|
||
|
|
for (i = 0; i < argc; i++) {
|
||
|
|
arg = argv[i];
|
||
|
|
if (arg->type != EJS_TYPE_STRING) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (ejsEvalScript(ep, arg->string, 0) < 0) {
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/*
|
||
|
|
* Return with the value of the last expression
|
||
|
|
*/
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
|
||
|
|
/* MOB -- need a real datatype returning int, int64, etc */
|
||
|
|
|
||
|
|
static int typeofProc(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
|
||
|
|
{
|
||
|
|
const struct {
|
||
|
|
EjsType type;
|
||
|
|
const char *name;
|
||
|
|
} types[] = {
|
||
|
|
{ EJS_TYPE_UNDEFINED, "undefined" },
|
||
|
|
#if EJS_ECMA_STND
|
||
|
|
{ EJS_TYPE_NULL, "object" },
|
||
|
|
#else
|
||
|
|
{ EJS_TYPE_NULL, "null" },
|
||
|
|
#endif
|
||
|
|
{ EJS_TYPE_BOOL, "boolean" },
|
||
|
|
{ EJS_TYPE_CMETHOD, "function" },
|
||
|
|
{ EJS_TYPE_FLOAT, "number" },
|
||
|
|
{ EJS_TYPE_INT, "number" },
|
||
|
|
{ EJS_TYPE_INT64, "number" },
|
||
|
|
{ EJS_TYPE_OBJECT, "object" },
|
||
|
|
{ EJS_TYPE_METHOD, "function" },
|
||
|
|
{ EJS_TYPE_STRING, "string" },
|
||
|
|
{ EJS_TYPE_STRING_CMETHOD, "function" },
|
||
|
|
{ EJS_TYPE_PTR, "pointer" }
|
||
|
|
};
|
||
|
|
const char *type;
|
||
|
|
int i;
|
||
|
|
|
||
|
|
type = NULL;
|
||
|
|
if (argc != 1) {
|
||
|
|
ejsError(ep, EJS_ARG_ERROR, "Bad args: typeof(var)");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (i = 0; i < MPR_ARRAY_SIZE(types); i++) {
|
||
|
|
if (argv[0]->type == types[i].type) {
|
||
|
|
type = types[i].name;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (type == NULL) {
|
||
|
|
mprAssert(type);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
ejsSetReturnValueToString(ep, type);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
/*
|
||
|
|
* Define the standard properties and methods inherited by all interpreters
|
||
|
|
* Obj is set to the global class in the default interpreter. When an
|
||
|
|
* interpreter attempts to write to any property, a copy will be written
|
||
|
|
* into the interpeters own global space. This is like a "copy-on-write".
|
||
|
|
*/
|
||
|
|
|
||
|
|
int ejsDefineGlobalProperties(Ejs *ep)
|
||
|
|
{
|
||
|
|
EjsVar *obj;
|
||
|
|
|
||
|
|
obj = ep->service->globalClass;
|
||
|
|
mprAssert(obj);
|
||
|
|
|
||
|
|
ejsSetPropertyToNull(ep, obj, "null");
|
||
|
|
ejsSetPropertyToUndefined(ep, obj, "undefined");
|
||
|
|
ejsSetPropertyToBoolean(ep, obj, "true", 1);
|
||
|
|
ejsSetPropertyToBoolean(ep, obj, "false", 0);
|
||
|
|
|
||
|
|
#if BLD_FEATURE_FLOATING_POINT
|
||
|
|
{
|
||
|
|
/* MOB. Fix. This generates warnings on some systems.
|
||
|
|
This is intended. */
|
||
|
|
double d = 0.0;
|
||
|
|
double e = 0.0;
|
||
|
|
ejsSetPropertyToFloat(ep, obj, "NaN", e / d);
|
||
|
|
|
||
|
|
d = MAX_FLOAT;
|
||
|
|
ejsSetPropertyToFloat(ep, obj, "Infinity", d * d);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if BLD_FEATURE_LEGACY_API
|
||
|
|
/*
|
||
|
|
* DEPRECATED: 2.0.
|
||
|
|
* So that ESP/ASP can ignore "language=javascript" statements
|
||
|
|
*/
|
||
|
|
ejsSetPropertyToInteger(ep, obj, "javascript", 0);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Extension methods. We go directly to the mpr property APIs for speed.
|
||
|
|
* Flags will cause the callbacks to be supplied the Ejs handle.
|
||
|
|
*/
|
||
|
|
ejsDefineCMethod(ep, obj, "assert", assertProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "breakpoint", breakpointProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "basename", basenameProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "dirname", dirnameProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "stripext", stripextProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "trim", trimProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "eval", evalScriptProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "exit", exitScript, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "print", printProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "println", printlnProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "sleep", sleepProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "sort", sortProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "time", timeProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "date", dateProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "strlen", strlenProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "strstr", strstrProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "typeof", typeofProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "toint", tointProc, EJS_NO_LOCAL);
|
||
|
|
|
||
|
|
ejsDefineStringCMethod(ep, obj, "include", includeProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineStringCMethod(ep, obj, "includeGlobal", includeGlobalProc,
|
||
|
|
EJS_NO_LOCAL);
|
||
|
|
ejsDefineStringCMethod(ep, obj, "trace", traceProc, EJS_NO_LOCAL);
|
||
|
|
|
||
|
|
#if BLD_DEBUG
|
||
|
|
ejsDefineCMethod(ep, obj, "printv", printvProc, EJS_NO_LOCAL);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if FUTURE
|
||
|
|
ejsDefineCMethod(ep, obj, "printf", printfProc, EJS_NO_LOCAL);
|
||
|
|
ejsDefineCMethod(ep, obj, "sprintf", sprintfProc, EJS_NO_LOCAL);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (ejsObjHasErrors(obj)) {
|
||
|
|
return MPR_ERR_CANT_INITIALIZE;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
|
||
|
|
#else
|
||
|
|
void ejsProcsDummy() {}
|
||
|
|
|
||
|
|
/******************************************************************************/
|
||
|
|
#endif /* BLD_FEATURE_EJS */
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Local variables:
|
||
|
|
* tab-width: 4
|
||
|
|
* c-basic-offset: 4
|
||
|
|
* End:
|
||
|
|
* vim:tw=78
|
||
|
|
* vim600: sw=4 ts=4 fdm=marker
|
||
|
|
* vim<600: sw=4 ts=4
|
||
|
|
*/
|