Fixed bug in 'multiline'

'incomplete' was popping error message that should be used in case
there is no more lines to complete the input, that is, 'pushline'
returns NULL, due to end of file.
This commit is contained in:
Roberto Ierusalimschy 2024-07-05 15:13:46 -03:00
parent 193bf7919e
commit 93fd6892f8
2 changed files with 19 additions and 14 deletions

28
lua.c
View File

@ -544,10 +544,8 @@ static int incomplete (lua_State *L, int status) {
if (status == LUA_ERRSYNTAX) {
size_t lmsg;
const char *msg = lua_tolstring(L, -1, &lmsg);
if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) {
lua_pop(L, 1);
if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0)
return 1;
}
}
return 0; /* else... */
}
@ -561,9 +559,9 @@ static int pushline (lua_State *L, int firstline) {
size_t l;
const char *prmt = get_prompt(L, firstline);
char *b = lua_readline(buffer, prmt);
if (b == NULL)
return 0; /* no input (prompt will be popped by caller) */
lua_pop(L, 1); /* remove prompt */
if (b == NULL)
return 0; /* no input */
l = strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
b[--l] = '\0'; /* remove it */
@ -584,11 +582,8 @@ static int addreturn (lua_State *L) {
const char *line = lua_tostring(L, -1); /* original line */
const char *retline = lua_pushfstring(L, "return %s;", line);
int status = luaL_loadbuffer(L, retline, strlen(retline), "=stdin");
if (status == LUA_OK) {
if (status == LUA_OK)
lua_remove(L, -2); /* remove modified line */
if (line[0] != '\0') /* non empty? */
lua_saveline(line); /* keep history */
}
else
lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */
return status;
@ -596,17 +591,18 @@ static int addreturn (lua_State *L) {
/*
** Read multiple lines until a complete Lua statement
** Read multiple lines until a complete Lua statement or an error not
** for an incomplete statement. Start with first line already read in
** the stack.
*/
static int multiline (lua_State *L) {
for (;;) { /* repeat until gets a complete statement */
size_t len;
const char *line = lua_tolstring(L, 1, &len); /* get what it has */
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
if (!incomplete(L, status) || !pushline(L, 0)) {
lua_saveline(line); /* keep history */
return status; /* cannot or should not try to add continuation line */
}
if (!incomplete(L, status) || !pushline(L, 0))
return status; /* should not or cannot try to add continuation line */
lua_remove(L, -2); /* remove error message (from incomplete line) */
lua_pushliteral(L, "\n"); /* add newline... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
@ -621,12 +617,16 @@ static int multiline (lua_State *L) {
** in the top of the stack.
*/
static int loadline (lua_State *L) {
const char *line;
int status;
lua_settop(L, 0);
if (!pushline(L, 1))
return -1; /* no input */
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
status = multiline(L); /* try as command, maybe with continuation lines */
line = lua_tostring(L, 1);
if (line[0] != '\0') /* non empty? */
lua_saveline(line); /* keep history */
lua_remove(L, 1); /* remove line from the stack */
lua_assert(lua_gettop(L) == 1);
return status;

View File

@ -349,6 +349,11 @@ prepfile("a = [[b\nc\nd\ne]]\n=a")
RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
checkprogout("b\nc\nd\ne\n\n")
-- input interrupted in continuation line
prepfile("a.\n")
RUN([[lua -i < %s > /dev/null 2> %s]], prog, out)
checkprogout("near <eof>\n")
local prompt = "alo"
prepfile[[ --
a = 2