aboutsummaryrefslogtreecommitdiff
path: root/src/lj_strfmt.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_strfmt.c76
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. */
311const 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. */
362const 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