summaryrefslogtreecommitdiff
path: root/src/lib_string.c
diff options
context:
space:
mode:
authorMike Pall <mike>2012-10-07 17:11:39 +0200
committerMike Pall <mike>2012-10-07 17:11:39 +0200
commit2f5ed5d0df518a08a52fc125473b17d3a46c2267 (patch)
treec2ea38696fa52c2d1d65ca9c20a7552fbe2da011 /src/lib_string.c
parent0561a5693884d76db5b75f7cc746478b325b311b (diff)
downloadluajit-2f5ed5d0df518a08a52fc125473b17d3a46c2267.tar.gz
luajit-2f5ed5d0df518a08a52fc125473b17d3a46c2267.tar.bz2
luajit-2f5ed5d0df518a08a52fc125473b17d3a46c2267.zip
From Lua 5.2: Add string.rep(s, n, sep).
Diffstat (limited to 'src/lib_string.c')
-rw-r--r--src/lib_string.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/src/lib_string.c b/src/lib_string.c
index b36fcd6d..9aa74d5c 100644
--- a/src/lib_string.c
+++ b/src/lib_string.c
@@ -86,22 +86,48 @@ LJLIB_ASM(string_sub) LJLIB_REC(string_range 1)
86LJLIB_ASM(string_rep) 86LJLIB_ASM(string_rep)
87{ 87{
88 GCstr *s = lj_lib_checkstr(L, 1); 88 GCstr *s = lj_lib_checkstr(L, 1);
89 int32_t len = (int32_t)s->len;
90 int32_t k = lj_lib_checkint(L, 2); 89 int32_t k = lj_lib_checkint(L, 2);
91 int64_t tlen = (int64_t)k * len; 90 GCstr *sep = lj_lib_optstr(L, 3);
91 int32_t len = (int32_t)s->len;
92 global_State *g = G(L);
93 int64_t tlen;
92 const char *src; 94 const char *src;
93 char *buf; 95 char *buf;
94 if (k <= 0) return FFH_RETRY; 96 if (k <= 0) {
95 if (tlen > LJ_MAX_STR) 97 empty:
96 lj_err_caller(L, LJ_ERR_STROV); 98 setstrV(L, L->base-1, &g->strempty);
97 buf = lj_str_needbuf(L, &G(L)->tmpbuf, (MSize)tlen); 99 return FFH_RES(1);
98 if (len <= 1) return FFH_RETRY; /* ASM code only needed buffer resize. */ 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) goto empty;
114 buf = lj_str_needbuf(L, &g->tmpbuf, (MSize)tlen);
99 src = strdata(s); 115 src = strdata(s);
116 if (sep) {
117 tlen -= sep->len; /* Ignore trailing separator. */
118 if (k > 1) { /* Paste one string and one separator. */
119 int32_t i;
120 i = 0; while (i < len) *buf++ = src[i++];
121 src = strdata(sep); len = sep->len;
122 i = 0; while (i < len) *buf++ = src[i++];
123 src = g->tmpbuf.buf; len += s->len; k--; /* Now copy that k-1 times. */
124 }
125 }
100 do { 126 do {
101 int32_t i = 0; 127 int32_t i = 0;
102 do { *buf++ = src[i++]; } while (i < len); 128 do { *buf++ = src[i++]; } while (i < len);
103 } while (--k > 0); 129 } while (--k > 0);
104 setstrV(L, L->base-1, lj_str_new(L, G(L)->tmpbuf.buf, (size_t)tlen)); 130 setstrV(L, L->base-1, lj_str_new(L, g->tmpbuf.buf, (size_t)tlen));
105 return FFH_RES(1); 131 return FFH_RES(1);
106} 132}
107 133