diff options
Diffstat (limited to 'src/lib_string.c')
| -rw-r--r-- | src/lib_string.c | 56 |
1 files changed, 13 insertions, 43 deletions
diff --git a/src/lib_string.c b/src/lib_string.c index cd673478..598cd93e 100644 --- a/src/lib_string.c +++ b/src/lib_string.c | |||
| @@ -85,53 +85,23 @@ LJLIB_ASM(string_sub) LJLIB_REC(string_range 1) | |||
| 85 | return FFH_RETRY; | 85 | return FFH_RETRY; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | LJLIB_ASM(string_rep) | 88 | LJLIB_CF(string_rep) |
| 89 | { | 89 | { |
| 90 | GCstr *s = lj_lib_checkstr(L, 1); | 90 | GCstr *s = lj_lib_checkstr(L, 1); |
| 91 | int32_t k = lj_lib_checkint(L, 2); | 91 | int32_t rep = lj_lib_checkint(L, 2); |
| 92 | GCstr *sep = lj_lib_optstr(L, 3); | 92 | GCstr *sep = lj_lib_optstr(L, 3); |
| 93 | int32_t len = (int32_t)s->len; | 93 | SBuf *sb = lj_buf_tmp_(L); |
| 94 | global_State *g = G(L); | 94 | if (sep && rep > 1) { |
| 95 | int64_t tlen; | 95 | GCstr *s2 = lj_buf_cat2str(L, sep, s); |
| 96 | if (k <= 0) { | 96 | lj_buf_reset(sb); |
| 97 | empty: | 97 | lj_buf_putstr(sb, s); |
| 98 | setstrV(L, L->base-1, &g->strempty); | 98 | s = s2; |
| 99 | return FFH_RES(1); | 99 | rep--; |
| 100 | } | ||
| 101 | if (sep) { | ||
| 102 | tlen = (int64_t)len + sep->len; | ||
| 103 | if (tlen > LJ_MAX_STR) | ||
| 104 | lj_err_caller(L, LJ_ERR_STROV); | ||
| 105 | tlen *= k; | ||
| 106 | if (tlen > LJ_MAX_STR) | ||
| 107 | lj_err_caller(L, LJ_ERR_STROV); | ||
| 108 | } else { | ||
| 109 | tlen = (int64_t)k * len; | ||
| 110 | if (tlen > LJ_MAX_STR) | ||
| 111 | lj_err_caller(L, LJ_ERR_STROV); | ||
| 112 | } | ||
| 113 | if (tlen == 0) { | ||
| 114 | goto empty; | ||
| 115 | } else { | ||
| 116 | char *buf = lj_buf_tmp(L, (MSize)tlen), *p = buf; | ||
| 117 | const char *src = strdata(s); | ||
| 118 | if (sep) { | ||
| 119 | tlen -= sep->len; /* Ignore trailing separator. */ | ||
| 120 | if (k > 1) { /* Paste one string and one separator. */ | ||
| 121 | int32_t i; | ||
| 122 | i = 0; while (i < len) *p++ = src[i++]; | ||
| 123 | src = strdata(sep); len = sep->len; | ||
| 124 | i = 0; while (i < len) *p++ = src[i++]; | ||
| 125 | src = buf; len += s->len; k--; /* Now copy that k-1 times. */ | ||
| 126 | } | ||
| 127 | } | ||
| 128 | do { | ||
| 129 | int32_t i = 0; | ||
| 130 | do { *p++ = src[i++]; } while (i < len); | ||
| 131 | } while (--k > 0); | ||
| 132 | setstrV(L, L->base-1, lj_str_new(L, buf, (size_t)tlen)); | ||
| 133 | } | 100 | } |
| 134 | return FFH_RES(1); | 101 | sb = lj_buf_putstr_rep(sb, s, rep); |
| 102 | setstrV(L, L->top-1, lj_buf_str(L, sb)); | ||
| 103 | lj_gc_check(L); | ||
| 104 | return 1; | ||
| 135 | } | 105 | } |
| 136 | 106 | ||
| 137 | LJLIB_ASM(string_reverse) LJLIB_REC(string_op IRCALL_lj_buf_putstr_reverse) | 107 | LJLIB_ASM(string_reverse) LJLIB_REC(string_op IRCALL_lj_buf_putstr_reverse) |
