From e8e39a277f9f81e5cb2638a1d13d4d96e3731b16 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 8 Apr 2016 18:15:02 -0300 Subject: 'string.format"%q"' now works for all basic types (nil, boolean, numbers, and strings) --- lstrlib.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/lstrlib.c b/lstrlib.c index 7b387fcb..29e6a250 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.243 2016/03/31 19:07:42 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.244 2016/04/07 15:40:07 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -921,11 +921,9 @@ static int lua_number2strx (lua_State *L, char *buff, int sz, #define MAX_FORMAT 32 -static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); +static void addquoted (luaL_Buffer *b, const char *s, size_t len) { luaL_addchar(b, '"'); - while (l--) { + while (len--) { if (*s == '"' || *s == '\\' || *s == '\n') { luaL_addchar(b, '\\'); luaL_addchar(b, *s); @@ -945,6 +943,38 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { luaL_addchar(b, '"'); } + +static void addliteral (lua_State *L, luaL_Buffer *b, int arg) { + switch (lua_type(L, arg)) { + case LUA_TSTRING: { + size_t len; + const char *s = lua_tolstring(L, arg, &len); + addquoted(b, s, len); + break; + } + case LUA_TNUMBER: { + if (!lua_isinteger(L, arg)) { /* write floats as hexa ('%a') */ + char *buff = luaL_prepbuffsize(b, MAX_ITEM); + lua_Number n = lua_tonumber(L, arg); + int nb = lua_number2strx(L, buff, MAX_ITEM, + "%" LUA_NUMBER_FRMLEN "a", n); + luaL_addsize(b, nb); + break; + } + /* else integers; write in "native" format *//* FALLTHROUGH */ + } + case LUA_TNIL: case LUA_TBOOLEAN: { + luaL_tolstring(L, arg, NULL); + luaL_addvalue(b); + break; + } + default: { + luaL_argerror(L, arg, "value has no literal form"); + } + } +} + + static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { const char *p = strfrmt; while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ @@ -1024,7 +1054,7 @@ static int str_format (lua_State *L) { break; } case 'q': { - addquoted(L, &b, arg); + addliteral(L, &b, arg); break; } case 's': { -- cgit v1.2.3-55-g6feb