It's been noted on this list[1] that many implementations of the printf() family support positional parameters, to help i18n/l10n efforts. The example in the archive message was printf("%2$s %1$s\n", "world!", "Hello"); /* prints "Hello world!\n" */ I haven't been able to find any discussion in the archives proposing similar behavior for Lua. Has this been kicked around before? Attached is a patch implementing the same behavior described in the POSIX extension[2]: instead of plain '%' starting a conversion sequence, you can use '%n$', where n is the integer index of format arguments. Some annotated examples after applying the patch against 5.1.4: > =string.format("%2$s %1$s\n", "world!", "Hello") Hello world! Straightforward enough. > =string.format("%3$d %1$d %d\n", 11, 22, 33, 44) 33 11 22 Mixing numbered (%n$) and unnumbered (%) specifications is undefined behavior in POSIX. But string.format doesn't do one big call to sprintf, so mixing doesn't need to cause errors; instead you just need to choose what behavior is least surprising. The patch as posted causes the index to be "permanently" updated, that is, after specifying n, the next unnumbered index is n+1, n+2, and so on rather than picking back up where it left off. Saving and restoring the unnumbered index would be easy also. > =string.format("%312ドル.5f %d\n", 11, 22, 33.33, 44) 33.33000 44 All the existing flags and other modifiers are still present. The n specifier has to be a nonnegative integral; getting that part wrong throws some errors. I'm not too keen about the wording on the error message in my patch, but at least something is caught. For instance: > =string.format("%-42$d\n", 1, 2, 3) stdin:1: invalid '%n$' position in format (out of range) stack traceback: [C]: in function 'format' stdin:1: in main chunk [C]: ? > =string.format("%7.7$d\n", 1, 2, 3, 4) stdin:1: invalid option '%$' to 'format' stack traceback: [C]: in function 'format' stdin:1: in main chunk [C]: ? Anyhow, patch follows. It's not for me to say if this is worth inclusion in base Lua source or in the "power patches" wiki, but I figured I'd throw it out there. (One note: the "if (isdigit(uchar(*strfrmt)))" which surrounds the change can be removed entirely and the enclosed block used as-is. The test is only to try and speed up the normal case in which unnumbered arguments are used, on the assumption that isdigit is a macro and strtol is expensive even when it fails instantly.) Comments welcome. -p [1] http://lua-users.org/lists/lua-l/2007-07/msg00088.html [2] http://www.opengroup.org/onlinepubs/009695399/functions/printf.html [3] there is no third note[4] [4] but there is a fourth!
Attachment:
strformat.patch
Description: Binary data