Extended shell. Previously was part of the ns tree. See README.html for
more details. git-svn-id: svn://10.0.0.236/trunk@17121 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
ce0f3f26ce
commit
745be1fd7d
229
mozilla/js/src/sh/README.html
Normal file
229
mozilla/js/src/sh/README.html
Normal file
@ -0,0 +1,229 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<META NAME="Author" CONTENT="Vladimir Livshits">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.05 [en]C-NSCP (WinNT; U) [Netscape]">
|
||||
<TITLE>Specification for the JavaScript shell</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<CENTER>
|
||||
<H3>
|
||||
Object hierarchy for JS Shell:</H3></CENTER>
|
||||
|
||||
<CENTER><TABLE BORDER=3 COLS=3 WIDTH="650" >
|
||||
<TR ALIGN=CENTER VALIGN=TOP>
|
||||
<TD ALIGN=CENTER VALIGN=TOP HEIGHT="100%">
|
||||
<TABLE BORDER=0 WIDTH="100%" >
|
||||
<TR>
|
||||
<TD BGCOLOR="#C0C0C0"><B> System </B></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD>
|
||||
<CENTER><B><FONT COLOR="#FF0000">Methods</FONT></B></CENTER>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
<B><TT>chdir</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>pipe</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>script</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>exit</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>system</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>gc</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<TT><B>call </B>(executes an external script)</TT></LI>
|
||||
|
||||
<LI>
|
||||
<TT><B>use</B> (make methods of the script you pass available. I.e. if
|
||||
you say <B>use('Foo','Bar')</B>, you can now call Foo.f() and Bar.f().
|
||||
Foo.eval() will evaluate all the code)</TT></LI>
|
||||
</UL>
|
||||
|
||||
<CENTER><B><FONT COLOR="#FF0000">Properties</FONT></B></CENTER>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
<B><TT><FONT COLOR="#330033">stdout</FONT></TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT><FONT COLOR="#330033">stdin</FONT></TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT><FONT COLOR="#330033">stderr </FONT></TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<TT><FONT COLOR="#330033"><B>platform </B>('PC', 'UNIX', 'MAC')</FONT></TT></LI>
|
||||
|
||||
<LI>
|
||||
<TT><FONT COLOR="#330033"><B>ARGV </B>(arguments passed to the script)</FONT></TT></LI>
|
||||
</UL>
|
||||
<B><FONT COLOR="#330033">Notes: <TT>pipe</TT> </FONT></B><FONT COLOR="#330033">works
|
||||
like backticks in Perl; <B><TT>script</TT></B> works the other way around,
|
||||
that is, you give it an array and it feeds the array to the executable
|
||||
you specify (somewhat similar to the script command on <TT>UNIX</TT>).</FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<TABLE BORDER=0 COLS=1 WIDTH="100%" >
|
||||
<TR>
|
||||
<TD BGCOLOR="#C0C0C0"><B>Environment</B></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD HEIGHT="100%">
|
||||
<CENTER><B><FONT COLOR="#FF0000">Properties</FONT></B></CENTER>
|
||||
|
||||
|
||||
<P><FONT COLOR="#330033">All environment variables become properties of
|
||||
<B><TT>Environment</TT></B>. Assigning to them actually changes the environment.</FONT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
|
||||
<TD>
|
||||
<TABLE BORDER=0 COLS=1 WIDTH="100%" >
|
||||
<TR>
|
||||
<TD BGCOLOR="#C0C0C0"><B>File</B></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD>
|
||||
<TABLE BORDER=0 COLS=2 WIDTH="100%" >
|
||||
<TR>
|
||||
<TD>
|
||||
<CENTER><B><FONT COLOR="#FF0000">Properties</FONT></B></CENTER>
|
||||
|
||||
<CENTER> </CENTER>
|
||||
|
||||
<LI>
|
||||
<B><TT>currentDir</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>length </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>parent </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>path </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>name </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>isDirectory</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>isFile </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>exists </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>canRead </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>canWrite </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>opened </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>type </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>mode </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>creationTime</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>lastModified</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>size </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>randomAccess</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>position</TT></B></LI>
|
||||
</TD>
|
||||
|
||||
<TD VALIGN=TOP>
|
||||
<CENTER><B><FONT COLOR="#FF0000">Methods</FONT></B></CENTER>
|
||||
|
||||
<CENTER> </CENTER>
|
||||
|
||||
<LI>
|
||||
<B><TT>open </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>close </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>remove </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>copyTo </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>renameTo</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>flush </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>skip </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>read </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>readln </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>readAll </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>write </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>writeln </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>writeAll</TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>list </TT></B></LI>
|
||||
|
||||
<LI>
|
||||
<B><TT>mkdir </TT></B></LI>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<I>(Henri's stuff)</I>
|
||||
<BR> </TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE></CENTER>
|
||||
|
||||
<BR>
|
||||
</BODY>
|
||||
</HTML>
|
||||
679
mozilla/js/src/sh/jssh.c
Normal file
679
mozilla/js/src/sh/jssh.c
Normal file
@ -0,0 +1,679 @@
|
||||
/* Copyright © 1998 Netscape Communications Corporation, All Rights Reserved.*/
|
||||
/* JavaScript Shell: jssh. Provides capabilities for calling commans, */
|
||||
/* loading libraries, etc. in JavaScript. For a full list of features, see
|
||||
/* README.html */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsapi.h" /* The API itself */
|
||||
#include "jsatom.h"
|
||||
#ifdef HAS_FILE_SUPPORT /* File object */
|
||||
# include "jsfile.h"
|
||||
#endif
|
||||
#ifdef LIVECONNECT /* link w/LiveConnect DLL */
|
||||
# include "jsjava.h"
|
||||
#endif
|
||||
#ifdef PERLCONNECT /* link w/PerlConnect DLL */
|
||||
# include "jsperl.h"
|
||||
#endif
|
||||
|
||||
#define STACK_CHUNK_SIZE 8192
|
||||
/* Platform-dependent stuff */
|
||||
#ifdef XP_PC
|
||||
# define ENVIRON _environ
|
||||
# define PUTENV _putenv
|
||||
# define POPEN _popen
|
||||
# define PCLOSE _pclose
|
||||
# define PLATFORM "PC"
|
||||
#elif XP_UNIX
|
||||
# define ENVIRON environ
|
||||
# define PUTENV putenv
|
||||
# define POPEN popen
|
||||
# define PCLOSE pclose
|
||||
# define PLATFORM "UNIX"
|
||||
#else
|
||||
# error "Platform not supported."
|
||||
#endif
|
||||
|
||||
|
||||
/* globals */
|
||||
JSRuntime *rt;
|
||||
JSContext *cx;
|
||||
JSObject *globalObject, *systemObject, *envObject;
|
||||
/* forward-definitions */
|
||||
static JSBool Process(JSContext*, JSObject*, char*, jsval *rval);
|
||||
static JSBool environment_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
|
||||
|
||||
/* global class */
|
||||
JSClass globalClass = {
|
||||
"Global", 0,
|
||||
JS_PropertyStub, JS_PropertyStub,JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
/* system class */
|
||||
JSClass systemClass = {
|
||||
"System", 0,
|
||||
JS_PropertyStub, JS_PropertyStub,JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
/* environment class */
|
||||
JSClass envClass = {
|
||||
"Environment", 0,
|
||||
JS_PropertyStub, environment_setProperty, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
/* object loaded via use() get a separate namespace of this type */
|
||||
JSClass libraryClass = {
|
||||
"Library", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
/****************************** global methods ******************************/
|
||||
/* load JS files in argv and execute them */
|
||||
static JSBool
|
||||
call(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
int i;
|
||||
char *ch;
|
||||
JSBool result = JS_TRUE;
|
||||
FILE *file;
|
||||
static char* processFile(FILE*);
|
||||
|
||||
for(i=0;i<argc;i++){
|
||||
char* source;
|
||||
JSObject *anonymous;
|
||||
|
||||
source = JS_GetStringBytes(JS_ValueToString(cx, argv[i]));
|
||||
file = fopen(source, "r");
|
||||
if(!file){
|
||||
JS_ReportError(cx, "Can't open %s", source);
|
||||
continue;
|
||||
}
|
||||
/* read file's contents */
|
||||
ch = processFile(file);
|
||||
/* define anonyous namespace */
|
||||
anonymous = JS_DefineObject(cx, globalObject, "__anonymous__",
|
||||
&globalClass, globalObject, JSPROP_ENUMERATE);
|
||||
/* evaluate script in that namespace. result gets accumulated */
|
||||
result = JS_EvaluateScript(cx, obj, ch, strlen(ch), "jssh", 0, rval) && result;
|
||||
free(ch);
|
||||
fclose(file);
|
||||
/* remove namespace */
|
||||
JS_DeleteProperty(cx, globalObject, "__anonymous__");
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Foo.eval() evaluates the content of a script preloaded with use('Foo') */
|
||||
static JSBool
|
||||
evalScript(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){
|
||||
void *p = JS_GetInstancePrivate(cx, obj, &libraryClass, NULL);
|
||||
JSScript *script;
|
||||
|
||||
if(!p)
|
||||
return JS_FALSE;
|
||||
|
||||
script = (JSScript*)p;
|
||||
return JS_ExecuteScript(cx, obj, script, rval);
|
||||
}
|
||||
|
||||
/*
|
||||
preload files specified in argv. for each create a namespace and
|
||||
make functions available within that namespace
|
||||
*/
|
||||
static JSBool
|
||||
use(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
int i;
|
||||
for(i=0;i<argc;i++){
|
||||
char source[256], *ch;
|
||||
FILE *file;
|
||||
JSObject *scriptObject;
|
||||
JSScript *script;
|
||||
JSIdArray *ida;
|
||||
jsval v;
|
||||
|
||||
strcpy(source, JS_GetStringBytes(JS_ValueToString(cx, argv[i])));
|
||||
/* add .js extention if necessary */
|
||||
if(!strstr(source, ".js")){
|
||||
strcat(source, ".js");
|
||||
}
|
||||
file = fopen(source, "r");
|
||||
if(!file){
|
||||
JS_ReportError(cx, "Can't open %s", source);
|
||||
return JS_FALSE;
|
||||
}
|
||||
/* remove '.js' extention */
|
||||
*(source + strlen(source)-3) = '\0';
|
||||
ch = processFile(file);
|
||||
scriptObject = JS_DefineObject(cx, globalObject, source, &libraryClass,
|
||||
NULL, JSPROP_ENUMERATE);
|
||||
if(!scriptObject){
|
||||
JS_ReportError(cx, "Can't create script");
|
||||
return JS_FALSE;
|
||||
}
|
||||
script = JS_CompileScript(cx, scriptObject, ch, strlen(ch), source, 0);
|
||||
fclose(file);
|
||||
if(!script){
|
||||
JS_ReportError(cx, "Can't compile script");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
ida = JS_Enumerate(cx, scriptObject);
|
||||
if(!ida){
|
||||
JS_ReportError(cx, "Can't enumerate");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* go through the properties and add them to the namespace we created */
|
||||
for (i = 0; i < ida->length; i++) {
|
||||
jschar *prop;
|
||||
JSString *str;
|
||||
|
||||
JS_IdToValue(cx, ida->vector[i], &v);
|
||||
str = JS_ValueToString(cx, v);
|
||||
prop = JS_GetStringChars(str);
|
||||
JS_GetUCProperty(cx, scriptObject, prop, JS_GetStringLength(str), &v);
|
||||
/* add v if it's a function */
|
||||
if(JS_TypeOfValue(cx, v) == JSTYPE_FUNCTION){
|
||||
char const *name = JS_GetFunctionName(JS_ValueToFunction(cx, v));
|
||||
JS_DefineProperty(cx, scriptObject, name, v, NULL, NULL,
|
||||
JSPROP_READONLY|JSPROP_PERMANENT);
|
||||
}
|
||||
}
|
||||
|
||||
/* save script as private data for the object */
|
||||
if(!JS_SetPrivate(cx, scriptObject, (void*)script)){
|
||||
return JS_FALSE;
|
||||
}
|
||||
JS_DefineFunction(cx, scriptObject, "eval", evalScript, 0, 0);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/********************** Define system methods **************************/
|
||||
/* a replacement for System.out.write */
|
||||
static JSBool
|
||||
system_print(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
int i;
|
||||
JSString *str;
|
||||
|
||||
for(i=0;i<argc;i++){
|
||||
str = JS_ValueToString(cx, argv[i]);
|
||||
if(!str) return JS_FALSE;
|
||||
printf("%s%s", i ? " ":"", JS_GetStringBytes(str));
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* run external commands */
|
||||
static JSBool
|
||||
system_system(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
JSString *str;
|
||||
int i;
|
||||
|
||||
for(i=0;i<argc;i++){
|
||||
str = JS_ValueToString(cx, argv[i]);
|
||||
/* TODO: error processing here */
|
||||
system(JS_GetStringBytes(str));
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* invoke the gc */
|
||||
static JSBool
|
||||
system_gc(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
JS_GC(cx);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Runs commands supplied as the first parameter and outputs a special file
|
||||
you can read info from.
|
||||
*/
|
||||
static JSBool
|
||||
system_pipe(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
JSObject *file;
|
||||
char *cmd;
|
||||
FILE *pipe; /* pipe we open */
|
||||
|
||||
if(argc!=1) return JS_FALSE; /* need one parameter -- command */
|
||||
|
||||
cmd = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
||||
|
||||
/* open the pipe */
|
||||
pipe = POPEN(cmd, "rt");
|
||||
|
||||
if(!pipe) {
|
||||
JS_ReportError(cx, "Attempt to read from a pipe failed, can't run command %s", cmd);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
file = js_NewFileObjectFromFILE(cx, pipe, cmd, JS_FALSE);
|
||||
*rval = OBJECT_TO_JSVAL(file);
|
||||
|
||||
//PCLOSE(pipe);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Runs command supplied as the first parameter and creates a special
|
||||
file you can write to
|
||||
*/
|
||||
static JSBool
|
||||
system_script(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
FILE *pipe; /* pipe we open */
|
||||
char *cmd;
|
||||
JSObject *file;
|
||||
|
||||
/* basic parameter checking */
|
||||
if(argc!=1){
|
||||
JS_ReportError(cx, "Expected one argument, i.e. file = script('ls')");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
cmd = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
||||
/* create pipe */
|
||||
pipe = POPEN(cmd, "wt");
|
||||
|
||||
if(!pipe){
|
||||
JS_ReportError(cx, "Attempt to read from a pipe failed, can't run command %s", cmd);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
file = js_NewFileObjectFromFILE(cx, pipe, cmd, JS_FALSE);
|
||||
*rval = OBJECT_TO_JSVAL(file);
|
||||
//PCLOSE(pipe);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* get/set version of the language */
|
||||
static JSBool
|
||||
system_version(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
if(argc){
|
||||
JS_SetVersion(cx, JSVAL_TO_INT(argv[0]));
|
||||
*rval = INT_TO_JSVAL(argv[0]);
|
||||
}else
|
||||
*rval = INT_TO_JSVAL(JS_GetVersion(cx));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* exit the interpreter. takes a return code */
|
||||
static JSBool
|
||||
system_exit(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
int32 ip;
|
||||
static void finilizeShell();
|
||||
|
||||
finilizeShell();
|
||||
|
||||
if(!argc)
|
||||
exit(0);
|
||||
else{
|
||||
exit(JS_ValueToInt32(cx, argv[0], &ip));
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* setter for Environment. updates the environment itself */
|
||||
static JSBool
|
||||
environment_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp){
|
||||
char envString[256];
|
||||
|
||||
printf("trying to set %s = %s\n", JS_GetStringBytes(JS_ValueToString(cx, id)),
|
||||
JS_GetStringBytes(JS_ValueToString(cx, *vp)));
|
||||
strcpy(envString, JS_GetStringBytes(JS_ValueToString(cx, id)));
|
||||
strcat(envString, "=");
|
||||
/* This is not preserved after the script terminates */
|
||||
strcat(envString, JS_GetStringBytes(JS_ValueToString(cx, *vp)));
|
||||
printf("%s\n", envString);
|
||||
PUTENV(envString);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* custom error reporter */
|
||||
static void
|
||||
errorReporter(JSContext *cx, const char *message, JSErrorReport *report){
|
||||
if(report == NULL)
|
||||
fprintf(stderr, "jssh: %s\n", message);
|
||||
else
|
||||
fprintf(stderr, "%s: line %i: error: %s\n",
|
||||
report->filename, report->lineno, message);
|
||||
}
|
||||
|
||||
/* add properties to Env */
|
||||
static void
|
||||
readEnvironment(JSContext *cx, JSObject *env){
|
||||
char **currEnvString;
|
||||
char currEnvName [256];
|
||||
char currEnvValue[1024]; /* this must be big enough */
|
||||
JSString *str;
|
||||
JSBool ok;
|
||||
|
||||
for(currEnvString = ENVIRON; *currEnvString!=NULL; currEnvString++){
|
||||
char *equal = strchr(*currEnvString, '=');
|
||||
strncpy(currEnvName, *currEnvString, equal-*currEnvString);
|
||||
currEnvName[equal-*currEnvString] = 0; /* append null char at the end */
|
||||
equal++;
|
||||
strncpy(currEnvValue, equal, *currEnvString+strlen(*currEnvString)-equal+1);
|
||||
str=JS_NewStringCopyZ(cx, equal/*, *currEnvString+strlen(*currEnvString)-equal*/);
|
||||
if(!str) {
|
||||
JS_ReportError(cx, "Error in readEnvironment, str==NULL");
|
||||
return;
|
||||
}
|
||||
/* add a new property to env object */
|
||||
ok = JS_DefineProperty(cx, env, currEnvName,
|
||||
STRING_TO_JSVAL(str), JS_PropertyStub, environment_setProperty,
|
||||
JSPROP_ENUMERATE|JSPROP_PERMANENT);
|
||||
if(!ok) {
|
||||
JS_ReportError(cx, "Error in readEnvironment, can't define a property");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* formatted output of the environment */
|
||||
static JSBool
|
||||
env_toString(JSContext *cx, JSObject *obj, int argc, jsval *argv, jsval* rval){
|
||||
char **currEnvString;
|
||||
char currEnvName [256];
|
||||
char currEnvValue[1024]; /* this must be big enough */
|
||||
|
||||
char *result;
|
||||
int len=0;
|
||||
|
||||
result = JS_malloc(cx, 1);
|
||||
strcpy(result, "");
|
||||
|
||||
for(currEnvString = ENVIRON; *currEnvString!=NULL; currEnvString++){
|
||||
char *equal = strchr(*currEnvString, '='), *p;
|
||||
char line[1024];
|
||||
|
||||
strncpy(currEnvName, *currEnvString, equal-*currEnvString);
|
||||
currEnvName[equal-*currEnvString] = 0; /* append null char at the end */
|
||||
equal++;
|
||||
strncpy(currEnvValue, equal, *currEnvString+strlen(*currEnvString)-equal+1);
|
||||
sprintf(line, "%25s = %s\n", currEnvName, currEnvValue);
|
||||
len+=strlen(line)+1;
|
||||
p = (char*)JS_realloc(cx, result, len*sizeof(char));
|
||||
if(!p) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
strcpy(p, result);
|
||||
result=p;
|
||||
strcat(result, line);
|
||||
}
|
||||
|
||||
//JS_free(cx, result);
|
||||
|
||||
*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, result));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
/* methods available */
|
||||
JSFunctionSpec globalMethods[] = {
|
||||
{"call", call, 0, 0},
|
||||
{"use", use, 0, 0},
|
||||
{ NULL, NULL, 0, 0}
|
||||
};
|
||||
|
||||
JSFunctionSpec systemMethods[] = {
|
||||
{"print", system_print, 0, 0},
|
||||
{"version", system_version, 0, 0},
|
||||
{"system", system_system, 0, 0},
|
||||
{"gc", system_gc, 0, 0},
|
||||
{"pipe", system_pipe, 0, 0},
|
||||
{"script", system_script, 0, 0},
|
||||
//{"help", system_help, 0, 0},
|
||||
{"exit", system_exit, 0, 0},
|
||||
{ NULL, NULL, 0, 0}
|
||||
};
|
||||
|
||||
JSFunctionSpec envMethods[] = {
|
||||
{"toString", env_toString, 0},
|
||||
{ NULL, NULL,0 }
|
||||
};
|
||||
|
||||
/*
|
||||
Read a file. Return it as a char pointer that
|
||||
should be deallocated. Ignore #-comments.
|
||||
*/
|
||||
static char*
|
||||
processFile(FILE *file){
|
||||
char *buf, *bufEnd, *bufUpto, ch;
|
||||
int bufLen, len;
|
||||
|
||||
/* read the file into memory */
|
||||
bufLen = 4096;
|
||||
buf = malloc(bufLen); /* allocate character buffer */
|
||||
bufEnd = buf+bufLen; /* end of the buffer */
|
||||
bufUpto = buf; /* current buffer pointer */
|
||||
|
||||
ch=fgetc(file); /* ignore first line starting with # */
|
||||
if(ch=='#')
|
||||
while((ch=fgetc(file))!=EOF) { if(ch=='\n') break;}
|
||||
else
|
||||
ungetc(ch,file);
|
||||
|
||||
while((len=fread(bufUpto, sizeof(char), bufEnd-bufUpto, file))>0){
|
||||
bufUpto+=len;
|
||||
if(bufUpto>=bufEnd) { /* expand the buffer if needed */
|
||||
bufLen+=bufLen;
|
||||
bufEnd=buf+bufLen;
|
||||
buf=realloc(buf,bufLen);
|
||||
}
|
||||
}
|
||||
*bufUpto = '\0';
|
||||
//puts(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
Read JavaScript source from file or stdin if !filename
|
||||
Evaluate it.
|
||||
*/
|
||||
static JSBool
|
||||
Process(JSContext *cx, JSObject *obj, char *filename, jsval *rval){
|
||||
FILE *file;
|
||||
char *ch;
|
||||
|
||||
/* Process the input */
|
||||
if(filename){
|
||||
file = fopen(filename, "r");
|
||||
if(file==NULL){
|
||||
JS_ReportError(cx, "Can't open %s\n", filename);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
ch = processFile(file);
|
||||
JS_EvaluateScript(cx, obj, ch, strlen(ch), "jssh", 0, rval);
|
||||
free(ch);
|
||||
fclose(file);
|
||||
}else{
|
||||
/* process input line-by-line */
|
||||
char line[256];
|
||||
int currLine = 0;
|
||||
JSString *str;
|
||||
do{
|
||||
printf("js> ");
|
||||
gets(line);
|
||||
*rval = JSVAL_VOID;
|
||||
JS_EvaluateScript(cx, globalObject, line, strlen(line), "jss", ++currLine, rval);
|
||||
if(!JSVAL_IS_VOID(*rval)){
|
||||
str=JS_ValueToString(cx, *rval);
|
||||
if(!str){
|
||||
JS_ReportError(cx, "Can't convert to string");
|
||||
}
|
||||
printf("%s\n", JS_GetStringBytes(str));
|
||||
}
|
||||
}while(1); /* need to type 'exit' to exit */
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
usage(){
|
||||
fprintf(stderr, "%s", JS_GetImplementationVersion());
|
||||
fputs("usage: js [ [scriptfile] [scriptarg...] | - ]", stderr);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
This is taken from JSShell.
|
||||
*/
|
||||
static int
|
||||
ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc){
|
||||
int i;
|
||||
char *filename;
|
||||
jsval *vector;
|
||||
jsval *p;
|
||||
JSObject *argsObj;
|
||||
jsval rval;
|
||||
JSBool ok;
|
||||
|
||||
/* prompt */
|
||||
if(argc<2 || !strcmp(argv[1], "-"))
|
||||
filename = NULL;
|
||||
else if(argc==2)
|
||||
filename = argv[1];
|
||||
else
|
||||
return usage();
|
||||
|
||||
vector = JS_malloc(cx, (argc-1)* sizeof(jsval));
|
||||
p = vector;
|
||||
if(!p){
|
||||
JS_ReportError(cx, "Error in ProcessArgs, p==NULL!");
|
||||
}
|
||||
|
||||
for(i=1;i<argc;i++){
|
||||
JSString *str = JS_NewStringCopyZ(cx, argv[i]);
|
||||
if (str == NULL) return 1;
|
||||
*p++ = STRING_TO_JSVAL(str);
|
||||
}
|
||||
|
||||
argsObj = JS_NewArrayObject(cx, argc-1, vector);
|
||||
if(!argsObj){
|
||||
JS_ReportError(cx, "Error in ProcessArgs, argsObj==NULL!");
|
||||
}
|
||||
|
||||
ok = JS_DefineProperty(cx, systemObject, "ARGV",
|
||||
OBJECT_TO_JSVAL(argsObj), NULL, NULL,
|
||||
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT);
|
||||
if(!ok){
|
||||
JS_ReportError(cx, "Can't define property ARGV");
|
||||
}
|
||||
|
||||
JS_free(cx, vector);
|
||||
|
||||
Process(cx, obj, filename, &rval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* perform basic initialization */
|
||||
static void
|
||||
initShell(){
|
||||
/* Initialization */
|
||||
rt = JS_Init(1000000L); /* runtime */
|
||||
|
||||
cx = JS_NewContext(rt, STACK_CHUNK_SIZE); /* context */
|
||||
|
||||
JS_SetErrorReporter(cx, errorReporter); /* error reporter */
|
||||
|
||||
globalObject = /* global object */
|
||||
JS_NewObject(cx, &globalClass, NULL, NULL);
|
||||
|
||||
JS_InitStandardClasses(cx, globalObject); /* basic classes */
|
||||
|
||||
#ifdef HAS_FILE_SUPPORT
|
||||
if(!js_InitFileClass(cx, globalObject)){ /* File */
|
||||
JS_ReportError(cx, "Failed to initialize File support");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LIVECONNECT
|
||||
if(!JSJ_SimpleInit(cx, globalObject, NULL, getenv("CLASSPATH"))){
|
||||
JS_ReportError(cx, "Failed to initialize LiveConnect");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* destroy everything */
|
||||
static void
|
||||
finilizeShell(){
|
||||
#ifdef LIVECONNECT
|
||||
JSJ_SimpleShutdown();
|
||||
#endif
|
||||
JS_GC(cx);
|
||||
JS_DestroyContext(cx);
|
||||
JS_Finish(rt);
|
||||
}
|
||||
|
||||
/* standard shell objects and properties */
|
||||
static void
|
||||
initShellObjects(){
|
||||
JSObject *stream;
|
||||
jsval v;
|
||||
extern JSObject* JS_InitPerlClass(JSContext*, JSObject*);
|
||||
|
||||
/* predefine System and its properties */
|
||||
JS_DefineFunctions(cx, globalObject, globalMethods);
|
||||
systemObject = /* System */
|
||||
JS_DefineObject(cx, globalObject, "System", &systemClass, NULL, JSPROP_ENUMERATE);
|
||||
JS_DefineFunctions(cx, systemObject, systemMethods);
|
||||
JS_DefineProperty(cx, systemObject, "platform",
|
||||
STRING_TO_JSVAL(JS_NewStringCopyZ(cx, PLATFORM)), NULL, NULL,
|
||||
JSPROP_ENUMERATE|JSPROP_PERMANENT|JSPROP_READONLY);
|
||||
/* define standard stream */
|
||||
stream = js_NewFileObjectFromFILE(cx, stdout, "Special file System.out", JS_TRUE);
|
||||
if (!stream){
|
||||
JS_ReportError(cx, "Can't create System.out");
|
||||
exit(1);
|
||||
}
|
||||
v=OBJECT_TO_JSVAL(stream);
|
||||
JS_SetProperty(cx, systemObject, "stdout", &v);
|
||||
|
||||
stream = js_NewFileObjectFromFILE(cx, stderr, "Special file System.err", JS_TRUE);
|
||||
if (!stream){
|
||||
JS_ReportError(cx, "Can't create System.err");
|
||||
exit(1);
|
||||
}
|
||||
v=OBJECT_TO_JSVAL(stream);
|
||||
JS_SetProperty(cx, systemObject, "stderr", &v);
|
||||
|
||||
stream = js_NewFileObjectFromFILE(cx, stdin, "Special file System.in", JS_TRUE);
|
||||
if (!stream){
|
||||
JS_ReportError(cx, "Can't create System.in");
|
||||
exit(1);
|
||||
}
|
||||
v=OBJECT_TO_JSVAL(stream);
|
||||
JS_SetProperty(cx, systemObject, "stdin", &v);
|
||||
|
||||
/* define Environment and populate it */
|
||||
envObject = /* Environment */
|
||||
JS_DefineObject(cx, globalObject, "Environment", &envClass, NULL, JSPROP_ENUMERATE);
|
||||
JS_DefineFunctions(cx, envObject, envMethods);
|
||||
readEnvironment(cx, envObject); /* initialize Environment's properties */
|
||||
#ifdef PERLCONNECT
|
||||
JS_InitPerlClass(cx, globalObject);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv){
|
||||
int result;
|
||||
|
||||
initShell();
|
||||
initShellObjects();
|
||||
result = ProcessArgs(cx, globalObject, argv, argc);
|
||||
finilizeShell();
|
||||
return result;
|
||||
}
|
||||
88
mozilla/js/src/sh/jssh.dsp
Normal file
88
mozilla/js/src/sh/jssh.dsp
Normal file
@ -0,0 +1,88 @@
|
||||
# Microsoft Developer Studio Project File - Name="jssh" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 5.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=jssh - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "jssh.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "jssh.mak" CFG="jssh - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "jssh - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "jssh - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "jssh - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "jssh - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /D "HAS_FILE_SUPPORT" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 js32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:".." /libpath:"../Debug" /libpath:"../Release"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "jssh - Win32 Release"
|
||||
# Name "jssh - Win32 Debug"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\jssh.c
|
||||
# End Source File
|
||||
# End Target
|
||||
# End Project
|
||||
29
mozilla/js/src/sh/jssh.dsw
Normal file
29
mozilla/js/src/sh/jssh.dsw
Normal file
@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 5.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "jssh"=.\jssh.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user