bug 413735 - consistent readline usage

This commit is contained in:
Andrei Saprykin 2009-01-13 16:35:47 +01:00
parent fd84f8a936
commit 5bef92a687
2 changed files with 97 additions and 27 deletions

View File

@ -160,7 +160,7 @@ STATIC CHAR *editinput();
#include <curses.h> #include <curses.h>
#include <term.h> #include <term.h>
#endif /* defined(USE_TERMCAP) */ #endif /* defined(USE_TERMCAP) */
/* /*
** TTY input/output functions. ** TTY input/output functions.
*/ */
@ -301,7 +301,7 @@ TTYinfo()
TTYrows = SCREEN_ROWS; TTYrows = SCREEN_ROWS;
} }
} }
STATIC void STATIC void
reposition() reposition()
@ -515,7 +515,7 @@ toggle_meta_mode()
rl_meta_chars = ! rl_meta_chars; rl_meta_chars = ! rl_meta_chars;
return redisplay(); return redisplay();
} }
STATIC CHAR * STATIC CHAR *
next_hist() next_hist()
@ -966,6 +966,9 @@ editinput()
case CSstay: case CSstay:
break; break;
} }
if (strlen(Line))
return Line;
free(Line);
return NULL; return NULL;
} }
@ -1052,7 +1055,7 @@ add_history(p)
#endif /* defined(UNIQUE_HISTORY) */ #endif /* defined(UNIQUE_HISTORY) */
hist_add((CHAR *)p); hist_add((CHAR *)p);
} }
STATIC STATUS STATIC STATUS
beg_line() beg_line()

View File

@ -142,8 +142,11 @@ extern void add_history(char *line);
JS_END_EXTERN_C JS_END_EXTERN_C
#endif #endif
static JSBool static char *
GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) { GetLine(FILE *file, const char * prompt)
{
size_t size;
char *buffer;
#ifdef EDITLINE #ifdef EDITLINE
/* /*
* Use readline only if file is stdin, because there's no way to specify * Use readline only if file is stdin, because there's no way to specify
@ -151,26 +154,54 @@ GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
*/ */
if (file == stdin) { if (file == stdin) {
char *linep = readline(prompt); char *linep = readline(prompt);
/*
* We set it to zero to avoid complaining about inappropriate ioctl
* for device in the case of EOF. Looks like errno == 251 if line is
* finished with EOF and errno == 25 if there is nothing left
* to read.
*/
if (errno == 251 || errno == 25)
errno = 0;
if (!linep) if (!linep)
return JS_FALSE; return NULL;
if (linep[0] != '\0') if (linep[0] != '\0')
add_history(linep); add_history(linep);
strcpy(bufp, linep); return linep;
JS_free(cx, linep); }
bufp += strlen(bufp);
*bufp++ = '\n';
*bufp = '\0';
} else
#endif #endif
{ size_t len = 0;
char line[256]; if (*prompt != '\0') {
fprintf(gOutFile, prompt); fprintf(gOutFile, prompt);
fflush(gOutFile); fflush(gOutFile);
if (!fgets(line, sizeof line, file))
return JS_FALSE;
strcpy(bufp, line);
} }
return JS_TRUE; size = 80;
buffer = (char *) malloc(size);
if (!buffer)
return NULL;
char *current = buffer;
while (fgets(current, size - len, file)) {
len += strlen(current);
char *t = buffer + len - 1;
if (*t == '\n') {
/* Line was read. We remove '\n' and exit. */
*t = '\0';
return buffer;
}
if (len + 1 == size) {
size = size * 2;
char *tmp = (char *) realloc(buffer, size);
if (!tmp) {
free(buffer);
return NULL;
}
buffer = tmp;
}
current = buffer + len;
}
if (len && !ferror(file))
return buffer;
free(buffer);
return NULL;
} }
/* Time-related portability helpers. */ /* Time-related portability helpers. */
@ -296,8 +327,8 @@ Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
JSScript *script; JSScript *script;
jsval result; jsval result;
JSString *str; JSString *str;
char buffer[4096]; char *buffer;
char *bufp; size_t size;
int lineno; int lineno;
int startline; int startline;
FILE *file; FILE *file;
@ -356,9 +387,9 @@ Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
/* It's an interactive filehandle; drop into read-eval-print loop. */ /* It's an interactive filehandle; drop into read-eval-print loop. */
lineno = 1; lineno = 1;
hitEOF = JS_FALSE; hitEOF = JS_FALSE;
size_t len;
buffer = NULL;
do { do {
bufp = buffer;
*bufp = '\0';
/* /*
* Accumulate lines until we get a 'compilable unit' - one that either * Accumulate lines until we get a 'compilable unit' - one that either
@ -368,17 +399,50 @@ Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
*/ */
startline = lineno; startline = lineno;
do { do {
if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) { errno = 0;
char *line = GetLine(file, startline == lineno ? "js> " : "");
if (!line) {
if (errno) {
JS_ReportError(cx, strerror(errno));
free(buffer);
return;
}
hitEOF = JS_TRUE; hitEOF = JS_TRUE;
break; break;
} }
bufp += strlen(bufp); if (!buffer) {
buffer = line;
len = strlen(buffer);
size = len + 1;
} else {
/**
* len + 1 is required to store '\n' in the end of line
*/
size_t newlen = strlen(line) + (len ? len + 1 : 0);
if (newlen + 1 > size) {
size = newlen + 1 > size * 2 ? newlen + 1 : size * 2;
char *newBuf = (char *) realloc(buffer, size);
if (!newBuf) {
free(buffer);
free(line);
JS_ReportOutOfMemory(cx);
return;
}
buffer = newBuf;
}
char *current = buffer + len;
if (startline != lineno)
*current++ = '\n';
strcpy(current, line);
len = newlen;
free(line);
}
lineno++; lineno++;
} while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer))); } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, len));
/* Clear any pending exception from previous failed compiles. */ /* Clear any pending exception from previous failed compiles. */
JS_ClearPendingException(cx); JS_ClearPendingException(cx);
script = JS_CompileScript(cx, obj, buffer, strlen(buffer), "typein", script = JS_CompileScript(cx, obj, buffer, len, "typein",
startline); startline);
if (script) { if (script) {
if (!compileOnly) { if (!compileOnly) {
@ -393,7 +457,10 @@ Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
} }
JS_DestroyScript(cx, script); JS_DestroyScript(cx, script);
} }
*buffer = '\0';
len = 0;
} while (!hitEOF && !gQuitting); } while (!hitEOF && !gQuitting);
free(buffer);
fprintf(gOutFile, "\n"); fprintf(gOutFile, "\n");
if (file != stdin) if (file != stdin)
fclose(file); fclose(file);