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) { if (status == LUA_ERRSYNTAX) {
size_t lmsg; size_t lmsg;
const char *msg = lua_tolstring(L, -1, &lmsg); const char *msg = lua_tolstring(L, -1, &lmsg);
if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0)
lua_pop(L, 1);
return 1; return 1;
}
} }
return 0; /* else... */ return 0; /* else... */
} }
@ -561,9 +559,9 @@ static int pushline (lua_State *L, int firstline) {
size_t l; size_t l;
const char *prmt = get_prompt(L, firstline); const char *prmt = get_prompt(L, firstline);
char *b = lua_readline(buffer, prmt); 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 */ lua_pop(L, 1); /* remove prompt */
if (b == NULL)
return 0; /* no input */
l = strlen(b); l = strlen(b);
if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
b[--l] = '\0'; /* remove it */ 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 *line = lua_tostring(L, -1); /* original line */
const char *retline = lua_pushfstring(L, "return %s;", line); const char *retline = lua_pushfstring(L, "return %s;", line);
int status = luaL_loadbuffer(L, retline, strlen(retline), "=stdin"); int status = luaL_loadbuffer(L, retline, strlen(retline), "=stdin");
if (status == LUA_OK) { if (status == LUA_OK)
lua_remove(L, -2); /* remove modified line */ lua_remove(L, -2); /* remove modified line */
if (line[0] != '\0') /* non empty? */
lua_saveline(line); /* keep history */
}
else else
lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */ lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */
return status; 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) { static int multiline (lua_State *L) {
for (;;) { /* repeat until gets a complete statement */ for (;;) { /* repeat until gets a complete statement */
size_t len; size_t len;
const char *line = lua_tolstring(L, 1, &len); /* get what it has */ const char *line = lua_tolstring(L, 1, &len); /* get what it has */
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
if (!incomplete(L, status) || !pushline(L, 0)) { if (!incomplete(L, status) || !pushline(L, 0))
lua_saveline(line); /* keep history */ return status; /* should not or cannot try to add continuation line */
return status; /* cannot or should not try to add continuation line */ lua_remove(L, -2); /* remove error message (from incomplete line) */
}
lua_pushliteral(L, "\n"); /* add newline... */ lua_pushliteral(L, "\n"); /* add newline... */
lua_insert(L, -2); /* ...between the two lines */ lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */ lua_concat(L, 3); /* join them */
@ -621,12 +617,16 @@ static int multiline (lua_State *L) {
** in the top of the stack. ** in the top of the stack.
*/ */
static int loadline (lua_State *L) { static int loadline (lua_State *L) {
const char *line;
int status; int status;
lua_settop(L, 0); lua_settop(L, 0);
if (!pushline(L, 1)) if (!pushline(L, 1))
return -1; /* no input */ return -1; /* no input */
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */ if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
status = multiline(L); /* try as command, maybe with continuation lines */ 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_remove(L, 1); /* remove line from the stack */
lua_assert(lua_gettop(L) == 1); lua_assert(lua_gettop(L) == 1);
return status; 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) RUN([[lua -e"_PROMPT='' _PROMPT2=''" -i < %s > %s]], prog, out)
checkprogout("b\nc\nd\ne\n\n") 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" local prompt = "alo"
prepfile[[ -- prepfile[[ --
a = 2 a = 2