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) |