** this function handles only '%d', '%c', '%f', '%p', '%s', and '%%' conventional formats, plus Lua-specific '%I' and '%U' */
| 594 | conventional formats, plus Lua-specific '%I' and '%U' |
| 595 | */ |
| 596 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
| 597 | BuffFS buff; /* holds last part of the result */ |
| 598 | const char *e; /* points to next '%' */ |
| 599 | initbuff(L, &buff); |
| 600 | while ((e = strchr(fmt, '%')) != NULL) { |
| 601 | addstr2buff(&buff, fmt, ct_diff2sz(e - fmt)); /* add 'fmt' up to '%' */ |
| 602 | switch (*(e + 1)) { /* conversion specifier */ |
| 603 | case 's': { /* zero-terminated string */ |
| 604 | const char *s = va_arg(argp, char *); |
| 605 | if (s == NULL) s = "(null)"; |
| 606 | addstr2buff(&buff, s, strlen(s)); |
| 607 | break; |
| 608 | } |
| 609 | case 'c': { /* an 'int' as a character */ |
| 610 | char c = cast_char(va_arg(argp, int)); |
| 611 | addstr2buff(&buff, &c, sizeof(char)); |
| 612 | break; |
| 613 | } |
| 614 | case 'd': { /* an 'int' */ |
| 615 | TValue num; |
| 616 | setivalue(&num, va_arg(argp, int)); |
| 617 | addnum2buff(&buff, &num); |
| 618 | break; |
| 619 | } |
| 620 | case 'I': { /* a 'lua_Integer' */ |
| 621 | TValue num; |
| 622 | setivalue(&num, cast_Integer(va_arg(argp, l_uacInt))); |
| 623 | addnum2buff(&buff, &num); |
| 624 | break; |
| 625 | } |
| 626 | case 'f': { /* a 'lua_Number' */ |
| 627 | TValue num; |
| 628 | setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber))); |
| 629 | addnum2buff(&buff, &num); |
| 630 | break; |
| 631 | } |
| 632 | case 'p': { /* a pointer */ |
| 633 | char bf[LUA_N2SBUFFSZ]; /* enough space for '%p' */ |
| 634 | void *p = va_arg(argp, void *); |
| 635 | int len = lua_pointer2str(bf, LUA_N2SBUFFSZ, p); |
| 636 | addstr2buff(&buff, bf, cast_uint(len)); |
| 637 | break; |
| 638 | } |
| 639 | case 'U': { /* an 'unsigned long' as a UTF-8 sequence */ |
| 640 | char bf[UTF8BUFFSZ]; |
| 641 | unsigned long arg = va_arg(argp, unsigned long); |
| 642 | int len = luaO_utf8esc(bf, cast(l_uint32, arg)); |
| 643 | addstr2buff(&buff, bf + UTF8BUFFSZ - len, cast_uint(len)); |
| 644 | break; |
| 645 | } |
| 646 | case '%': { |
| 647 | addstr2buff(&buff, "%", 1); |
| 648 | break; |
| 649 | } |
| 650 | default: { |
| 651 | addstr2buff(&buff, e, 2); /* keep unknown format in the result */ |
| 652 | break; |
| 653 | } |
no test coverage detected