зеркало из https://github.com/mozilla/pjs.git
bug 300841: Provide a readline function to allow scripts run under the js shell to access stdin. r+a=brendan
This commit is contained in:
Родитель
7b8f6fcef2
Коммит
ad48b3491d
73
js/src/js.c
73
js/src/js.c
|
@ -583,6 +583,77 @@ Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* function readline()
|
||||
* Provides a hook for scripts to read a line from stdin.
|
||||
*/
|
||||
static JSBool
|
||||
ReadLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
#define BUFSIZE 256
|
||||
FILE *from;
|
||||
char *buf, *tmp;
|
||||
size_t bufsize, buflength, gotlength;
|
||||
JSString *str;
|
||||
|
||||
from = stdin;
|
||||
buflength = 0;
|
||||
bufsize = BUFSIZE;
|
||||
buf = JS_malloc(cx, bufsize);
|
||||
if (!buf)
|
||||
return JS_FALSE;
|
||||
|
||||
while ((gotlength =
|
||||
js_fgets(buf + buflength, bufsize - buflength, from)) > 0) {
|
||||
buflength += gotlength;
|
||||
|
||||
/* Are we done? */
|
||||
if (buf[buflength - 1] == '\n') {
|
||||
buf[buflength - 1] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
/* Else, grow our buffer for another pass. */
|
||||
tmp = JS_realloc(cx, buf, bufsize * 2);
|
||||
if (!tmp) {
|
||||
JS_free(cx, buf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
bufsize *= 2;
|
||||
buf = tmp;
|
||||
}
|
||||
|
||||
/* Treat the empty string specially. */
|
||||
if (buflength == 0) {
|
||||
*rval = JS_GetEmptyStringValue(cx);
|
||||
JS_free(cx, buf);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Shrink the buffer to the real size */
|
||||
tmp = JS_realloc(cx, buf, buflength);
|
||||
if (!tmp) {
|
||||
JS_free(cx, buf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
buf = tmp;
|
||||
|
||||
/*
|
||||
* Turn buf into a JSString. Note that buflength includes the trailing null
|
||||
* character.
|
||||
*/
|
||||
str = JS_NewString(cx, buf, buflength - 1);
|
||||
if (!str) {
|
||||
JS_free(cx, buf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
|
@ -1476,6 +1547,7 @@ static JSFunctionSpec shell_functions[] = {
|
|||
{"version", Version, 0},
|
||||
{"options", Options, 0},
|
||||
{"load", Load, 1},
|
||||
{"readline", ReadLine, 0},
|
||||
{"print", Print, 0},
|
||||
{"help", Help, 0},
|
||||
{"quit", Quit, 0},
|
||||
|
@ -1513,6 +1585,7 @@ static char *shell_help_messages[] = {
|
|||
"version([number]) Get or set JavaScript version number",
|
||||
"options([option ...]) Get or toggle JavaScript options",
|
||||
"load(['foo.js' ...]) Load files named by string arguments",
|
||||
"readline() Read a single line from stdin",
|
||||
"print([exp ...]) Evaluate and print expressions",
|
||||
"help([name ...]) Display usage and help messages",
|
||||
"quit() Quit the shell",
|
||||
|
|
|
@ -322,8 +322,8 @@ js_CloseTokenStream(JSContext *cx, JSTokenStream *ts)
|
|||
return !ts->file || fclose(ts->file) == 0;
|
||||
}
|
||||
|
||||
static int
|
||||
my_fgets(char *buf, int size, FILE *file)
|
||||
JS_FRIEND_API(int)
|
||||
js_fgets(char *buf, int size, FILE *file)
|
||||
{
|
||||
int n, i, c;
|
||||
JSBool crflag;
|
||||
|
@ -373,7 +373,7 @@ GetChar(JSTokenStream *ts)
|
|||
|
||||
/* Fill ts->userbuf so that \r and \r\n convert to \n. */
|
||||
crflag = (ts->flags & TSF_CRFLAG) != 0;
|
||||
len = my_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file);
|
||||
len = js_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file);
|
||||
if (len <= 0) {
|
||||
ts->flags |= TSF_EOF;
|
||||
return EOF;
|
||||
|
|
|
@ -276,6 +276,9 @@ js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp);
|
|||
extern JS_FRIEND_API(JSBool)
|
||||
js_CloseTokenStream(JSContext *cx, JSTokenStream *ts);
|
||||
|
||||
extern JS_FRIEND_API(int)
|
||||
js_fgets(char *buf, int size, FILE *file);
|
||||
|
||||
/*
|
||||
* Initialize the scanner, installing JS keywords into cx's global scope.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче