Browse Source

New conversion specifier '%p' for 'string.format'

The call 'string.format("%p", val)' gives a Lua equivalent to the
C API function 'lua_topointer'.
pull/22/head
Roberto Ierusalimschy 6 years ago
parent
commit
dfebe439db
  1. 5
      lstrlib.c
  2. 13
      manual/manual.of
  3. 16
      testes/strings.lua

5
lstrlib.c

@ -1185,6 +1185,11 @@ static int str_format (lua_State *L) {
nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n);
break;
}
case 'p': {
const void *p = lua_topointer(L, arg);
nb = l_sprintf(buff, MAX_ITEM, form, p);
break;
}
case 'q': {
if (form[2] != '\0') /* modifiers? */
return luaL_error(L, "specifier '%%q' cannot have modifiers");

13
manual/manual.of

@ -6751,8 +6751,7 @@ Returns a formatted version of its variable number of arguments
following the description given in its first argument (which must be a string).
The format string follows the same rules as the @ANSI{sprintf}.
The only differences are that the conversion specifiers and modifiers
@T{*}, @id{h}, @id{L}, @id{l}, @id{n},
and @id{p} are not supported
@T{*}, @id{h}, @id{L}, @id{l}, and @id{n} are not supported
and that there is an extra specifier, @id{q}.
The specifier @id{q} formats booleans, nil, numbers, and strings
@ -6791,6 +6790,14 @@ it is converted to one following the same rules of @Lid{tostring}.
If the specifier has any modifier,
the corresponding string argument should not contain @x{embedded zeros}.
The specifier @id{p} formats the pointer
returned by @Lid{lua_topointer}.
That gives a unique string identifier for tables, userdata,
threads, strings, and functions.
For other values (numbers, nil, booleans),
this specifier results in a string representing
the pointer @id{NULL}.
}
@LibEntry{string.gmatch (s, pattern [, init])|
@ -8768,7 +8775,7 @@ address space.)
}
@item{
The constant @Lid{LUA_ERRGCMM} was removed.
The constant @id{LUA_ERRGCMM} was removed.
Errors in finalizers are never propagated;
instead, they generate a warning.
}

16
testes/strings.lua

@ -153,6 +153,22 @@ else -- compatible coercion
assert(tostring(-1203 + 0.0) == "-1203")
end
do -- tests for '%p' format
-- not much to test, as C does not specify what '%p' does.
-- ("The value of the pointer is converted to a sequence of printing
-- characters, in an implementation-defined manner.")
local null = string.format("%p", nil)
assert(string.format("%p", {}) ~= null)
assert(string.format("%p", 4) == null)
assert(string.format("%p", print) ~= null)
assert(string.format("%p", coroutine.running()) ~= null)
assert(string.format("%p", {}) ~= string.format("%p", {}))
assert(string.format("%p", string.rep("a", 10)) ==
string.format("%p", string.rep("a", 10))) -- short strings
assert(string.format("%p", string.rep("a", 300)) ~=
string.format("%p", string.rep("a", 300))) -- long strings
assert(#string.format("%90p", {}) == 90)
end
x = '"ílo"\n\\'
assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\')

Loading…
Cancel
Save