diff options
author | Mike Pall <mike> | 2012-10-07 17:11:39 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-10-07 17:11:39 +0200 |
commit | 2f5ed5d0df518a08a52fc125473b17d3a46c2267 (patch) | |
tree | c2ea38696fa52c2d1d65ca9c20a7552fbe2da011 /src/lib_string.c | |
parent | 0561a5693884d76db5b75f7cc746478b325b311b (diff) | |
download | luajit-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.c | 42 |
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) | |||
86 | LJLIB_ASM(string_rep) | 86 | LJLIB_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 | ||