diff options
| -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\\') |
