diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-13 14:04:01 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-03-13 14:04:01 -0300 |
commit | dfebe439db76b5c9fd9b4e3877857e2449c8ad87 (patch) | |
tree | c31aa85dc53d1c0e0704060f313b682765dd459c | |
parent | cf71a5ddc742692fad813f89f1c9ef53e1ffde0f (diff) | |
download | lua-dfebe439db76b5c9fd9b4e3877857e2449c8ad87.tar.gz lua-dfebe439db76b5c9fd9b4e3877857e2449c8ad87.tar.bz2 lua-dfebe439db76b5c9fd9b4e3877857e2449c8ad87.zip |
New conversion specifier '%p' for 'string.format'
The call 'string.format("%p", val)' gives a Lua equivalent to the
C API function 'lua_topointer'.
-rw-r--r-- | lstrlib.c | 5 | ||||
-rw-r--r-- | manual/manual.of | 13 | ||||
-rw-r--r-- | testes/strings.lua | 16 |
3 files changed, 31 insertions, 3 deletions
@@ -1185,6 +1185,11 @@ static int str_format (lua_State *L) { | |||
1185 | nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n); | 1185 | nb = l_sprintf(buff, MAX_ITEM, form, (LUAI_UACNUMBER)n); |
1186 | break; | 1186 | break; |
1187 | } | 1187 | } |
1188 | case 'p': { | ||
1189 | const void *p = lua_topointer(L, arg); | ||
1190 | nb = l_sprintf(buff, MAX_ITEM, form, p); | ||
1191 | break; | ||
1192 | } | ||
1188 | case 'q': { | 1193 | case 'q': { |
1189 | if (form[2] != '\0') /* modifiers? */ | 1194 | if (form[2] != '\0') /* modifiers? */ |
1190 | return luaL_error(L, "specifier '%%q' cannot have modifiers"); | 1195 | return luaL_error(L, "specifier '%%q' cannot have modifiers"); |
diff --git a/manual/manual.of b/manual/manual.of index 9c8ab033..2eb8773f 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
@@ -6751,8 +6751,7 @@ Returns a formatted version of its variable number of arguments | |||
6751 | following the description given in its first argument (which must be a string). | 6751 | following the description given in its first argument (which must be a string). |
6752 | The format string follows the same rules as the @ANSI{sprintf}. | 6752 | The format string follows the same rules as the @ANSI{sprintf}. |
6753 | The only differences are that the conversion specifiers and modifiers | 6753 | The only differences are that the conversion specifiers and modifiers |
6754 | @T{*}, @id{h}, @id{L}, @id{l}, @id{n}, | 6754 | @T{*}, @id{h}, @id{L}, @id{l}, and @id{n} are not supported |
6755 | and @id{p} are not supported | ||
6756 | and that there is an extra specifier, @id{q}. | 6755 | and that there is an extra specifier, @id{q}. |
6757 | 6756 | ||
6758 | The specifier @id{q} formats booleans, nil, numbers, and strings | 6757 | 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}. | |||
6791 | If the specifier has any modifier, | 6790 | If the specifier has any modifier, |
6792 | the corresponding string argument should not contain @x{embedded zeros}. | 6791 | the corresponding string argument should not contain @x{embedded zeros}. |
6793 | 6792 | ||
6793 | The specifier @id{p} formats the pointer | ||
6794 | returned by @Lid{lua_topointer}. | ||
6795 | That gives a unique string identifier for tables, userdata, | ||
6796 | threads, strings, and functions. | ||
6797 | For other values (numbers, nil, booleans), | ||
6798 | this specifier results in a string representing | ||
6799 | the pointer @id{NULL}. | ||
6800 | |||
6794 | } | 6801 | } |
6795 | 6802 | ||
6796 | @LibEntry{string.gmatch (s, pattern [, init])| | 6803 | @LibEntry{string.gmatch (s, pattern [, init])| |
@@ -8768,7 +8775,7 @@ address space.) | |||
8768 | } | 8775 | } |
8769 | 8776 | ||
8770 | @item{ | 8777 | @item{ |
8771 | The constant @Lid{LUA_ERRGCMM} was removed. | 8778 | The constant @id{LUA_ERRGCMM} was removed. |
8772 | Errors in finalizers are never propagated; | 8779 | Errors in finalizers are never propagated; |
8773 | instead, they generate a warning. | 8780 | instead, they generate a warning. |
8774 | } | 8781 | } |
diff --git a/testes/strings.lua b/testes/strings.lua index da53a87e..8bcbb391 100644 --- a/testes/strings.lua +++ b/testes/strings.lua | |||
@@ -153,6 +153,22 @@ else -- compatible coercion | |||
153 | assert(tostring(-1203 + 0.0) == "-1203") | 153 | assert(tostring(-1203 + 0.0) == "-1203") |
154 | end | 154 | end |
155 | 155 | ||
156 | do -- tests for '%p' format | ||
157 | -- not much to test, as C does not specify what '%p' does. | ||
158 | -- ("The value of the pointer is converted to a sequence of printing | ||
159 | -- characters, in an implementation-defined manner.") | ||
160 | local null = string.format("%p", nil) | ||
161 | assert(string.format("%p", {}) ~= null) | ||
162 | assert(string.format("%p", 4) == null) | ||
163 | assert(string.format("%p", print) ~= null) | ||
164 | assert(string.format("%p", coroutine.running()) ~= null) | ||
165 | assert(string.format("%p", {}) ~= string.format("%p", {})) | ||
166 | assert(string.format("%p", string.rep("a", 10)) == | ||
167 | string.format("%p", string.rep("a", 10))) -- short strings | ||
168 | assert(string.format("%p", string.rep("a", 300)) ~= | ||
169 | string.format("%p", string.rep("a", 300))) -- long strings | ||
170 | assert(#string.format("%90p", {}) == 90) | ||
171 | end | ||
156 | 172 | ||
157 | x = '"ílo"\n\\' | 173 | x = '"ílo"\n\\' |
158 | assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\') | 174 | assert(string.format('%q%s', x, x) == '"\\"ílo\\"\\\n\\\\""ílo"\n\\') |