From 93fd6892f85ecd8a4e82d2339016a9f71a42d0e8 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 5 Jul 2024 15:13:46 -0300 Subject: [PATCH] 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. --- lua.c | 28 ++++++++++++++-------------- testes/main.lua | 5 +++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/lua.c b/lua.c index 51979a8b..bff6a8f5 100644 --- a/lua.c +++ b/lua.c @@ -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; diff --git a/testes/main.lua b/testes/main.lua index 9a86fb5a..17fbcb61 100644 --- a/testes/main.lua +++ b/testes/main.lua @@ -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 \n") + local prompt = "alo" prepfile[[ -- a = 2