lua_pushfstring should support the "%.*s" format
| Newsgroups | gmane.comp.lang.lua.general |
|---|---|
| Message-ID | <[email protected]> |
Hi, Cheap substrings, embedded \0s, strings with explicit length - I'd like that. Can we have this merged? (and having e.g. "%.3f" would be nice too) Thanks, Z -- You received this message because you are subscribed to the Google Groups "lua-l" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion visit https://groups.google.com/d/msgid/lua-l/0b3c33e3-a35e-4c4e-afea-677f391d38f3n%40googlegroups.com.
pushfstring_with_string_length.patch
(text/x-patch, 1.9 KB)
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -596,16 +596,31 @@
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
BuffFS buff; /* holds last part of the result */
const char *e; /* points to next '%' */
initbuff(L, &buff);
while ((e = strchr(fmt, '%')) != NULL) {
+ int prec = -1;
addstr2buff(&buff, fmt, ct_diff2sz(e - fmt)); /* add 'fmt' up to '%' */
- switch (*(e + 1)) { /* conversion specifier */
- case 's': { /* zero-terminated string */
+
+ fmt = e + 1; /* skip '%' */
+ if (*fmt == '.') { /* precision specifier */
+ fmt++;
+ if (*fmt == '*') {
+ fmt++;
+ prec = va_arg(argp, int);
+ } else {
+ char *tmp;
+ prec = strtol(fmt, &tmp, 10);
+ fmt = tmp;
+ }
+ }
+
+ switch (*fmt++) { /* conversion specifier */
+ case 's': { /* string */
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
- addstr2buff(&buff, s, strlen(s));
+ addstr2buff(&buff, s, prec >= 0 ? (size_t)prec : strlen(s));
break;
}
case 'c': { /* an 'int' as a character */
char c = cast_char(va_arg(argp, int));
addstr2buff(&buff, &c, sizeof(char));
@@ -641,20 +656,16 @@
unsigned long arg = va_arg(argp, unsigned long);
int len = luaO_utf8esc(bf, cast(l_uint32, arg));
addstr2buff(&buff, bf + UTF8BUFFSZ - len, cast_uint(len));
break;
}
- case '%': {
- addstr2buff(&buff, "%", 1);
- break;
- }
+ case '%': e++; /* fall-thru */
default: {
- addstr2buff(&buff, e, 2); /* keep unknown format in the result */
+ addstr2buff(&buff, e, ct_diff2sz(fmt - e)); /* add format to result */
break;
}
}
- fmt = e + 2; /* skip '%' and the specifier */
}
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
return clearbuff(&buff); /* empty buffer into a new string */
}