aboutsummaryrefslogtreecommitdiff
path: root/src/lib_string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_string.c')
-rw-r--r--src/lib_string.c56
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
88LJLIB_ASM(string_rep) 88LJLIB_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
137LJLIB_ASM(string_reverse) LJLIB_REC(string_op IRCALL_lj_buf_putstr_reverse) 107LJLIB_ASM(string_reverse) LJLIB_REC(string_op IRCALL_lj_buf_putstr_reverse)