diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_strfmt.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/lj_strfmt.c b/src/lj_strfmt.c index 9aaf08e2..1fe9308d 100644 --- a/src/lj_strfmt.c +++ b/src/lj_strfmt.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include "lj_obj.h" | 11 | #include "lj_obj.h" |
12 | #include "lj_buf.h" | 12 | #include "lj_buf.h" |
13 | #include "lj_state.h" | ||
13 | #include "lj_char.h" | 14 | #include "lj_char.h" |
14 | #include "lj_strfmt.h" | 15 | #include "lj_strfmt.h" |
15 | 16 | ||
@@ -293,3 +294,78 @@ SBuf *lj_strfmt_putnum(SBuf *sb, SFormat sf, lua_Number n) | |||
293 | return sb; | 294 | return sb; |
294 | } | 295 | } |
295 | 296 | ||
297 | /* -- Internal string formatting ------------------------------------------ */ | ||
298 | |||
299 | /* | ||
300 | ** These functions are only used for lua_pushfstring(), lua_pushvfstring() | ||
301 | ** and for internal string formatting (e.g. error messages). Caveat: unlike | ||
302 | ** string.format(), only a limited subset of formats and flags are supported! | ||
303 | ** | ||
304 | ** LuaJIT has support for a couple more formats than Lua 5.1/5.2: | ||
305 | ** - %d %u %o %x with full formatting, 32 bit integers only. | ||
306 | ** - %f and other FP formats are really %.14g. | ||
307 | ** - %s %c %p without formatting. | ||
308 | */ | ||
309 | |||
310 | /* Push formatted message as a string object to Lua stack. va_list variant. */ | ||
311 | const char *lj_strfmt_pushvf(lua_State *L, const char *fmt, va_list argp) | ||
312 | { | ||
313 | SBuf *sb = lj_buf_tmp_(L); | ||
314 | FormatState fs; | ||
315 | SFormat sf; | ||
316 | GCstr *str; | ||
317 | lj_strfmt_init(&fs, fmt, strlen(fmt)); | ||
318 | while ((sf = lj_strfmt_parse(&fs)) != STRFMT_EOF) { | ||
319 | switch (STRFMT_TYPE(sf)) { | ||
320 | case STRFMT_LIT: | ||
321 | lj_buf_putmem(sb, fs.str, fs.len); | ||
322 | break; | ||
323 | case STRFMT_INT: | ||
324 | lj_strfmt_putxint(sb, sf, va_arg(argp, int32_t)); | ||
325 | break; | ||
326 | case STRFMT_UINT: | ||
327 | lj_strfmt_putxint(sb, sf, va_arg(argp, uint32_t)); | ||
328 | break; | ||
329 | case STRFMT_NUM: { | ||
330 | TValue tv; | ||
331 | tv.n = va_arg(argp, lua_Number); | ||
332 | setsbufP(sb, lj_str_bufnum(lj_buf_more(sb, LJ_STR_NUMBUF), &tv)); | ||
333 | break; | ||
334 | } | ||
335 | case STRFMT_STR: { | ||
336 | const char *s = va_arg(argp, char *); | ||
337 | if (s == NULL) s = "(null)"; | ||
338 | lj_buf_putmem(sb, s, (MSize)strlen(s)); | ||
339 | break; | ||
340 | } | ||
341 | case STRFMT_CHAR: | ||
342 | lj_buf_putb(sb, va_arg(argp, int)); | ||
343 | break; | ||
344 | case STRFMT_PTR: | ||
345 | setsbufP(sb, lj_str_bufptr(lj_buf_more(sb, LJ_STR_PTRBUF), | ||
346 | va_arg(argp, void *))); | ||
347 | break; | ||
348 | case STRFMT_ERR: | ||
349 | default: | ||
350 | lj_buf_putb(sb, '?'); | ||
351 | lua_assert(0); | ||
352 | break; | ||
353 | } | ||
354 | } | ||
355 | str = lj_buf_str(L, sb); | ||
356 | setstrV(L, L->top, str); | ||
357 | incr_top(L); | ||
358 | return strdata(str); | ||
359 | } | ||
360 | |||
361 | /* Push formatted message as a string object to Lua stack. Vararg variant. */ | ||
362 | const char *lj_strfmt_pushf(lua_State *L, const char *fmt, ...) | ||
363 | { | ||
364 | const char *msg; | ||
365 | va_list argp; | ||
366 | va_start(argp, fmt); | ||
367 | msg = lj_strfmt_pushvf(L, fmt, argp); | ||
368 | va_end(argp); | ||
369 | return msg; | ||
370 | } | ||
371 | |||