diff options
| author | Mike Pall <mike> | 2021-06-01 05:14:18 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2021-06-01 05:14:18 +0200 |
| commit | edd5cbadc5cdc7b5b66d5340ee97c5abe5a3892a (patch) | |
| tree | 053c8bb18f0b9de559a4b712062fd99e96849be7 /src/lib_string.c | |
| parent | 50d6883e6027c4c2f9a5e495fee6b7fff1bd73c9 (diff) | |
| download | luajit-edd5cbadc5cdc7b5b66d5340ee97c5abe5a3892a.tar.gz luajit-edd5cbadc5cdc7b5b66d5340ee97c5abe5a3892a.tar.bz2 luajit-edd5cbadc5cdc7b5b66d5340ee97c5abe5a3892a.zip | |
String buffers, part 2c: abstract out string.format.
Sponsored by fmad.io.
Diffstat (limited to 'src/lib_string.c')
| -rw-r--r-- | src/lib_string.c | 85 |
1 files changed, 5 insertions, 80 deletions
diff --git a/src/lib_string.c b/src/lib_string.c index 4a3ff3729..75d855d6b 100644 --- a/src/lib_string.c +++ b/src/lib_string.c | |||
| @@ -640,89 +640,14 @@ LJLIB_CF(string_gsub) | |||
| 640 | 640 | ||
| 641 | /* ------------------------------------------------------------------------ */ | 641 | /* ------------------------------------------------------------------------ */ |
| 642 | 642 | ||
| 643 | /* Emulate tostring() inline. */ | ||
| 644 | static GCstr *string_fmt_tostring(lua_State *L, int arg, int retry) | ||
| 645 | { | ||
| 646 | TValue *o = L->base+arg-1; | ||
| 647 | cTValue *mo; | ||
| 648 | lj_assertL(o < L->top, "bad usage"); /* Caller already checks for existence. */ | ||
| 649 | if (LJ_LIKELY(tvisstr(o))) | ||
| 650 | return strV(o); | ||
| 651 | if (retry != 2 && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { | ||
| 652 | copyTV(L, L->top++, mo); | ||
| 653 | copyTV(L, L->top++, o); | ||
| 654 | lua_call(L, 1, 1); | ||
| 655 | copyTV(L, L->base+arg-1, --L->top); | ||
| 656 | return NULL; /* Buffer may be overwritten, retry. */ | ||
| 657 | } | ||
| 658 | return lj_strfmt_obj(L, o); | ||
| 659 | } | ||
| 660 | |||
| 661 | LJLIB_CF(string_format) LJLIB_REC(.) | 643 | LJLIB_CF(string_format) LJLIB_REC(.) |
| 662 | { | 644 | { |
| 663 | int arg, top = (int)(L->top - L->base); | ||
| 664 | GCstr *fmt; | ||
| 665 | SBuf *sb; | ||
| 666 | FormatState fs; | ||
| 667 | SFormat sf; | ||
| 668 | int retry = 0; | 645 | int retry = 0; |
| 669 | again: | 646 | SBuf *sb; |
| 670 | arg = 1; | 647 | do { |
| 671 | sb = lj_buf_tmp_(L); | 648 | sb = lj_buf_tmp_(L); |
| 672 | fmt = lj_lib_checkstr(L, arg); | 649 | retry = lj_strfmt_putarg(L, sb, 1, -retry); |
| 673 | lj_strfmt_init(&fs, strdata(fmt), fmt->len); | 650 | } while (retry > 0); |
| 674 | while ((sf = lj_strfmt_parse(&fs)) != STRFMT_EOF) { | ||
| 675 | if (sf == STRFMT_LIT) { | ||
| 676 | lj_buf_putmem(sb, fs.str, fs.len); | ||
| 677 | } else if (sf == STRFMT_ERR) { | ||
| 678 | lj_err_callerv(L, LJ_ERR_STRFMT, strdata(lj_str_new(L, fs.str, fs.len))); | ||
| 679 | } else { | ||
| 680 | if (++arg > top) | ||
| 681 | luaL_argerror(L, arg, lj_obj_typename[0]); | ||
| 682 | switch (STRFMT_TYPE(sf)) { | ||
| 683 | case STRFMT_INT: | ||
| 684 | if (tvisint(L->base+arg-1)) { | ||
| 685 | int32_t k = intV(L->base+arg-1); | ||
| 686 | if (sf == STRFMT_INT) | ||
| 687 | lj_strfmt_putint(sb, k); /* Shortcut for plain %d. */ | ||
| 688 | else | ||
| 689 | lj_strfmt_putfxint(sb, sf, k); | ||
| 690 | } else { | ||
| 691 | lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg)); | ||
| 692 | } | ||
| 693 | break; | ||
| 694 | case STRFMT_UINT: | ||
| 695 | if (tvisint(L->base+arg-1)) | ||
| 696 | lj_strfmt_putfxint(sb, sf, intV(L->base+arg-1)); | ||
| 697 | else | ||
| 698 | lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg)); | ||
| 699 | break; | ||
| 700 | case STRFMT_NUM: | ||
| 701 | lj_strfmt_putfnum(sb, sf, lj_lib_checknum(L, arg)); | ||
| 702 | break; | ||
| 703 | case STRFMT_STR: { | ||
| 704 | GCstr *str = string_fmt_tostring(L, arg, retry); | ||
| 705 | if (str == NULL) | ||
| 706 | retry = 1; | ||
| 707 | else if ((sf & STRFMT_T_QUOTED)) | ||
| 708 | lj_strfmt_putquoted(sb, str); /* No formatting. */ | ||
| 709 | else | ||
| 710 | lj_strfmt_putfstr(sb, sf, str); | ||
| 711 | break; | ||
| 712 | } | ||
| 713 | case STRFMT_CHAR: | ||
| 714 | lj_strfmt_putfchar(sb, sf, lj_lib_checkint(L, arg)); | ||
| 715 | break; | ||
| 716 | case STRFMT_PTR: /* No formatting. */ | ||
| 717 | lj_strfmt_putptr(sb, lj_obj_ptr(G(L), L->base+arg-1)); | ||
| 718 | break; | ||
| 719 | default: | ||
| 720 | lj_assertL(0, "bad string format type"); | ||
| 721 | break; | ||
| 722 | } | ||
| 723 | } | ||
| 724 | } | ||
| 725 | if (retry++ == 1) goto again; | ||
| 726 | setstrV(L, L->top-1, lj_buf_str(L, sb)); | 651 | setstrV(L, L->top-1, lj_buf_str(L, sb)); |
| 727 | lj_gc_check(L); | 652 | lj_gc_check(L); |
| 728 | return 1; | 653 | return 1; |
