34#if !defined(LUA_MAXCAPTURES)
35#define LUA_MAXCAPTURES 32
40#define uchar(c) ((unsigned char)(c))
47#define MAX_SIZET ((size_t)(~(size_t)0))
50 (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
57 luaL_checklstring(L, 1, &l);
58 lua_pushinteger(L, (lua_Integer)l);
71static size_t posrelatI (lua_Integer pos,
size_t len) {
76 else if (pos < -(lua_Integer)len)
78 else return len + (size_t)pos + 1;
87static size_t getendpos (
lua_State *L,
int arg, lua_Integer def,
89 lua_Integer pos = luaL_optinteger(L, arg, def);
90 if (pos > (lua_Integer)len)
94 else if (pos < -(lua_Integer)len)
96 else return len + (size_t)pos + 1;
102 const char *s = luaL_checklstring(L, 1, &l);
103 size_t start = posrelatI(luaL_checkinteger(L, 2), l);
104 size_t end = getendpos(L, 3, -1, l);
106 lua_pushlstring(L, s + start - 1, (end - start) + 1);
107 else lua_pushliteral(L,
"");
115 const char *s = luaL_checklstring(L, 1, &l);
116 char *p = luaL_buffinitsize(L, &b, l);
117 for (i = 0; i < l; i++)
119 luaL_pushresultsize(&b, l);
128 const char *s = luaL_checklstring(L, 1, &l);
129 char *p = luaL_buffinitsize(L, &b, l);
131 p[i] = tolower(uchar(s[i]));
132 luaL_pushresultsize(&b, l);
141 const char *s = luaL_checklstring(L, 1, &l);
142 char *p = luaL_buffinitsize(L, &b, l);
144 p[i] = toupper(uchar(s[i]));
145 luaL_pushresultsize(&b, l);
152 const char *s = luaL_checklstring(L, 1, &l);
153 lua_Integer n = luaL_checkinteger(L, 2);
154 const char *sep = luaL_optlstring(L, 3,
"", &lsep);
156 lua_pushliteral(L,
"");
157 else if (l_unlikely(l + lsep < l || l + lsep > MAXSIZE / n))
158 return luaL_error(L,
"resulting string too large");
160 size_t totallen = (size_t)n * l + (
size_t)(n - 1) * lsep;
162 char *p = luaL_buffinitsize(L, &b, totallen);
164 memcpy(p, s, l *
sizeof(
char)); p += l;
166 memcpy(p, sep, lsep *
sizeof(
char));
170 memcpy(p, s, l *
sizeof(
char));
171 luaL_pushresultsize(&b, totallen);
179 const char *s = luaL_checklstring(L, 1, &l);
180 lua_Integer pi = luaL_optinteger(L, 2, 1);
181 size_t posi = posrelatI(pi, l);
182 size_t pose = getendpos(L, 3, pi, l);
184 if (posi > pose)
return 0;
185 if (l_unlikely(pose - posi >= (
size_t)INT_MAX))
186 return luaL_error(L,
"string slice too long");
187 n = (int)(pose - posi) + 1;
188 luaL_checkstack(L, n,
"string slice too long");
190 lua_pushinteger(L, uchar(s[posi+i-1]));
196 int n = lua_gettop(L);
199 char *p = luaL_buffinitsize(L, &b, n);
200 for (i=1; i<=n; i++) {
201 lua_Unsigned c = (lua_Unsigned)luaL_checkinteger(L, i);
202 luaL_argcheck(L, c <= (lua_Unsigned)UCHAR_MAX, i,
"value out of range");
205 luaL_pushresultsize(&b, n);
222static int writer (
lua_State *L,
const void *b,
size_t size,
void *ud) {
226 luaL_buffinit(L, &state->B);
228 luaL_addlstring(&state->B, (
const char *)b, size);
235 int strip = lua_toboolean(L, 2);
236 luaL_checktype(L, 1, LUA_TFUNCTION);
239 if (l_unlikely(lua_dump(L, writer, &state, strip) != 0))
240 return luaL_error(L,
"unable to dump given function");
241 luaL_pushresult(&state.B);
253#if defined(LUA_NOCVTS2N)
257static const luaL_Reg stringmetamethods[] = {
264static int tonum (
lua_State *L,
int arg) {
265 if (lua_type(L, arg) == LUA_TNUMBER) {
266 lua_pushvalue(L, arg);
271 const char *s = lua_tolstring(L, arg, &len);
272 return (s != NULL && lua_stringtonumber(L, s) == len + 1);
277static void trymt (
lua_State *L,
const char *mtname) {
279 if (l_unlikely(lua_type(L, 2) == LUA_TSTRING ||
280 !luaL_getmetafield(L, 2, mtname)))
281 luaL_error(L,
"attempt to %s a '%s' with a '%s'", mtname + 2,
282 luaL_typename(L, -2), luaL_typename(L, -1));
288static int arith (
lua_State *L,
int op,
const char *mtname) {
289 if (tonum(L, 1) && tonum(L, 2))
298 return arith(L, LUA_OPADD,
"__add");
302 return arith(L, LUA_OPSUB,
"__sub");
306 return arith(L, LUA_OPMUL,
"__mul");
310 return arith(L, LUA_OPMOD,
"__mod");
314 return arith(L, LUA_OPPOW,
"__pow");
318 return arith(L, LUA_OPDIV,
"__div");
322 return arith(L, LUA_OPIDIV,
"__idiv");
326 return arith(L, LUA_OPUNM,
"__unm");
330static const luaL_Reg stringmetamethods[] = {
331 {
"__add", arith_add},
332 {
"__sub", arith_sub},
333 {
"__mul", arith_mul},
334 {
"__mod", arith_mod},
335 {
"__pow", arith_pow},
336 {
"__div", arith_div},
337 {
"__idiv", arith_idiv},
338 {
"__unm", arith_unm},
354#define CAP_UNFINISHED (-1)
355#define CAP_POSITION (-2)
359 const char *src_init;
368 } capture[LUA_MAXCAPTURES];
373static const char *match (
MatchState *ms,
const char *s,
const char *p);
377#if !defined(MAXCCALLS)
383#define SPECIALS "^$*+?.([%-"
386static int check_capture (
MatchState *ms,
int l) {
388 if (l_unlikely(l < 0 || l >= ms->level ||
389 ms->capture[l].len == CAP_UNFINISHED))
390 return luaL_error(ms->L,
"invalid capture index %%%d", l + 1);
396 int level = ms->level;
397 for (level--; level>=0; level--)
398 if (ms->capture[level].len == CAP_UNFINISHED)
return level;
399 return luaL_error(ms->L,
"invalid pattern capture");
403static const char *classend (
MatchState *ms,
const char *p) {
406 if (l_unlikely(p == ms->p_end))
407 luaL_error(ms->L,
"malformed pattern (ends with '%%')");
413 if (l_unlikely(p == ms->p_end))
414 luaL_error(ms->L,
"malformed pattern (missing ']')");
415 if (*(p++) == L_ESC && p < ms->p_end)
427static int match_class (
int c,
int cl) {
429 switch (tolower(cl)) {
430 case 'a' : res = isalpha(c);
break;
431 case 'c' : res = iscntrl(c);
break;
432 case 'd' : res = isdigit(c);
break;
433 case 'g' : res = isgraph(c);
break;
434 case 'l' : res = islower(c);
break;
435 case 'p' : res = ispunct(c);
break;
436 case 's' : res = isspace(c);
break;
437 case 'u' : res = isupper(c);
break;
438 case 'w' : res = isalnum(c);
break;
439 case 'x' : res = isxdigit(c);
break;
440 case 'z' : res = (c == 0);
break;
441 default:
return (cl == c);
443 return (islower(cl) ? res : !res);
447static int matchbracketclass (
int c,
const char *p,
const char *ec) {
456 if (match_class(c, uchar(*p)))
459 else if ((*(p+1) ==
'-') && (p+2 < ec)) {
461 if (uchar(*(p-2)) <= c && c <= uchar(*p))
464 else if (uchar(*p) == c)
return sig;
470static int singlematch (
MatchState *ms,
const char *s,
const char *p,
472 if (s >= ms->src_end)
478 case L_ESC:
return match_class(c, uchar(*(p+1)));
479 case '[':
return matchbracketclass(c, p, ep-1);
480 default:
return (uchar(*p) == c);
486static const char *matchbalance (
MatchState *ms,
const char *s,
488 if (l_unlikely(p >= ms->p_end - 1))
489 luaL_error(ms->L,
"malformed pattern (missing arguments to '%%b')");
490 if (*s != *p)
return NULL;
495 while (++s < ms->src_end) {
497 if (--cont == 0)
return s+1;
499 else if (*s == b) cont++;
506static const char *max_expand (
MatchState *ms,
const char *s,
507 const char *p,
const char *ep) {
509 while (singlematch(ms, s + i, p, ep))
513 const char *res = match(ms, (s+i), ep+1);
521static const char *min_expand (
MatchState *ms,
const char *s,
522 const char *p,
const char *ep) {
524 const char *res = match(ms, s, ep+1);
527 else if (singlematch(ms, s, p, ep))
534static const char *start_capture (
MatchState *ms,
const char *s,
535 const char *p,
int what) {
537 int level = ms->level;
538 if (level >= LUA_MAXCAPTURES) luaL_error(ms->L,
"too many captures");
539 ms->capture[level].init = s;
540 ms->capture[level].len = what;
542 if ((res=match(ms, s, p)) == NULL)
548static const char *end_capture (
MatchState *ms,
const char *s,
550 int l = capture_to_close(ms);
552 ms->capture[l].len = s - ms->capture[l].init;
553 if ((res = match(ms, s, p)) == NULL)
554 ms->capture[l].len = CAP_UNFINISHED;
559static const char *match_capture (
MatchState *ms,
const char *s,
int l) {
561 l = check_capture(ms, l);
562 len = ms->capture[l].len;
563 if ((
size_t)(ms->src_end-s) >= len &&
564 memcmp(ms->capture[l].init, s, len) == 0)
570static const char *match (
MatchState *ms,
const char *s,
const char *p) {
571 if (l_unlikely(ms->matchdepth-- == 0))
572 luaL_error(ms->L,
"pattern too complex");
574 if (p != ms->p_end) {
578 s = start_capture(ms, s, p + 2, CAP_POSITION);
580 s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
584 s = end_capture(ms, s, p + 1);
588 if ((p + 1) != ms->p_end)
590 s = (s == ms->src_end) ? s : NULL;
596 s = matchbalance(ms, s, p + 2);
603 const char *ep;
char previous;
605 if (l_unlikely(*p !=
'['))
606 luaL_error(ms->L,
"missing '[' after '%%f' in pattern");
607 ep = classend(ms, p);
608 previous = (s == ms->src_init) ?
'\0' : *(s - 1);
609 if (!matchbracketclass(uchar(previous), p, ep - 1) &&
610 matchbracketclass(uchar(*s), p, ep - 1)) {
616 case '0':
case '1':
case '2':
case '3':
617 case '4':
case '5':
case '6':
case '7':
618 case '8':
case '9': {
619 s = match_capture(ms, s, uchar(*(p + 1)));
630 const char *ep = classend(ms, p);
632 if (!singlematch(ms, s, p, ep)) {
633 if (*ep ==
'*' || *ep ==
'?' || *ep ==
'-') {
634 p = ep + 1;
goto init;
643 if ((res = match(ms, s + 1, ep + 1)) != NULL)
646 p = ep + 1;
goto init;
654 s = max_expand(ms, s, p, ep);
657 s = min_expand(ms, s, p, ep);
660 s++; p = ep;
goto init;
673static const char *lmemfind (
const char *s1,
size_t l1,
674 const char *s2,
size_t l2) {
675 if (l2 == 0)
return s1;
676 else if (l2 > l1)
return NULL;
681 while (l1 > 0 && (init = (
const char *)memchr(s1, *s2, l1)) != NULL) {
683 if (memcmp(init, s2+1, l2) == 0)
702static size_t get_onecapture (
MatchState *ms,
int i,
const char *s,
703 const char *e,
const char **cap) {
704 if (i >= ms->level) {
705 if (l_unlikely(i != 0))
706 luaL_error(ms->L,
"invalid capture index %%%d", i + 1);
711 ptrdiff_t capl = ms->capture[i].len;
712 *cap = ms->capture[i].init;
713 if (l_unlikely(capl == CAP_UNFINISHED))
714 luaL_error(ms->L,
"unfinished capture");
715 else if (capl == CAP_POSITION)
716 lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
725static void push_onecapture (
MatchState *ms,
int i,
const char *s,
728 ptrdiff_t l = get_onecapture(ms, i, s, e, &cap);
729 if (l != CAP_POSITION)
730 lua_pushlstring(ms->L, cap, l);
735static int push_captures (
MatchState *ms,
const char *s,
const char *e) {
737 int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
738 luaL_checkstack(ms->L, nlevels,
"too many captures");
739 for (i = 0; i < nlevels; i++)
740 push_onecapture(ms, i, s, e);
746static int nospecials (
const char *p,
size_t l) {
749 if (strpbrk(p + upto, SPECIALS))
751 upto += strlen(p + upto) + 1;
758 const char *s,
size_t ls,
const char *p,
size_t lp) {
760 ms->matchdepth = MAXCCALLS;
762 ms->src_end = s + ls;
769 lua_assert(ms->matchdepth == MAXCCALLS);
773static int str_find_aux (
lua_State *L,
int find) {
775 const char *s = luaL_checklstring(L, 1, &ls);
776 const char *p = luaL_checklstring(L, 2, &lp);
777 size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1;
783 if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
785 const char *s2 = lmemfind(s + init, ls - init, p, lp);
787 lua_pushinteger(L, (s2 - s) + 1);
788 lua_pushinteger(L, (s2 - s) + lp);
794 const char *s1 = s + init;
795 int anchor = (*p ==
'^');
799 prepstate(&ms, L, s, ls, p, lp);
803 if ((res=match(&ms, s1, p)) != NULL) {
805 lua_pushinteger(L, (s1 - s) + 1);
806 lua_pushinteger(L, res - s);
807 return push_captures(&ms, NULL, 0) + 2;
810 return push_captures(&ms, s1, res);
812 }
while (s1++ < ms.src_end && !anchor);
820 return str_find_aux(L, 1);
825 return str_find_aux(L, 0);
833 const char *lastmatch;
842 for (src = gm->src; src <= gm->ms.src_end; src++) {
844 reprepstate(&gm->ms);
845 if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
846 gm->src = gm->lastmatch = e;
847 return push_captures(&gm->ms, src, e);
856 const char *s = luaL_checklstring(L, 1, &ls);
857 const char *p = luaL_checklstring(L, 2, &lp);
858 size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1;
864 prepstate(&gm->ms, L, s, ls, p, lp);
865 gm->src = s + init; gm->p = p; gm->lastmatch = NULL;
866 lua_pushcclosure(L, gmatch_aux, 3);
875 const char *news = lua_tolstring(L, 3, &l);
877 while ((p = (
char *)memchr(news, L_ESC, l)) != NULL) {
878 luaL_addlstring(b, news, p - news);
883 luaL_addlstring(b, s, e - s);
884 else if (isdigit(uchar(*p))) {
886 ptrdiff_t resl = get_onecapture(ms, *p -
'1', s, e, &cap);
887 if (resl == CAP_POSITION)
890 luaL_addlstring(b, cap, resl);
893 luaL_error(L,
"invalid use of '%c' in replacement string", L_ESC);
897 luaL_addlstring(b, news, l);
907 const char *e,
int tr) {
910 case LUA_TFUNCTION: {
913 n = push_captures(ms, s, e);
918 push_onecapture(ms, 0, s, e);
927 if (!lua_toboolean(L, -1)) {
929 luaL_addlstring(b, s, e - s);
932 else if (l_unlikely(!lua_isstring(L, -1)))
933 return luaL_error(L,
"invalid replacement value (a %s)",
934 luaL_typename(L, -1));
944 const char *src = luaL_checklstring(L, 1, &srcl);
945 const char *p = luaL_checklstring(L, 2, &lp);
946 const char *lastmatch = NULL;
947 int tr = lua_type(L, 3);
948 lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1);
949 int anchor = (*p ==
'^');
954 luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
955 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
956 "string/function/table");
957 luaL_buffinit(L, &b);
961 prepstate(&ms, L, src, srcl, p, lp);
965 if ((e = match(&ms, src, p)) != NULL && e != lastmatch) {
967 changed = add_value(&ms, &b, src, e, tr) | changed;
970 else if (src < ms.src_end)
971 luaL_addchar(&b, *src++);
978 luaL_addlstring(&b, src, ms.src_end-src);
981 lua_pushinteger(L, n);
995#if !defined(lua_number2strx)
1001#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
1010#define L_NBFD ((l_floatatt(MANT_DIG) - 1)%4 + 1)
1016static lua_Number adddigit (
char *buff,
int n, lua_Number x) {
1017 lua_Number dd = l_mathop(floor)(x);
1019 buff[n] = (d < 10 ? d +
'0' : d - 10 +
'a');
1024static int num2straux (
char *buff,
int sz, lua_Number x) {
1026 if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL)
1027 return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x);
1030 return l_sprintf(buff, sz, LUA_NUMBER_FMT
"x0p+0", (LUAI_UACNUMBER)x);
1034 lua_Number m = l_mathop(frexp)(x, &e);
1040 buff[n++] =
'0'; buff[n++] =
'x';
1041 m = adddigit(buff, n++, m * (1 << L_NBFD));
1044 buff[n++] = lua_getlocaledecpoint();
1046 m = adddigit(buff, n++, m * 16);
1049 n += l_sprintf(buff + n, sz - n,
"p%+d", e);
1056static int lua_number2strx (
lua_State *L,
char *buff,
int sz,
1057 const char *fmt, lua_Number x) {
1058 int n = num2straux(buff, sz, x);
1059 if (fmt[SIZELENMOD] ==
'A') {
1061 for (i = 0; i < n; i++)
1062 buff[i] = toupper(uchar(buff[i]));
1064 else if (l_unlikely(fmt[SIZELENMOD] !=
'a'))
1065 return luaL_error(L,
"modifiers for format '%%a'/'%%A' not implemented");
1078#define MAX_ITEMF (110 + l_floatatt(MAX_10_EXP))
1093#if !defined(L_FMTFLAGSF)
1096#define L_FMTFLAGSF "-+#0 "
1099#define L_FMTFLAGSX "-#0"
1102#define L_FMTFLAGSI "-+0 "
1105#define L_FMTFLAGSU "-0"
1108#define L_FMTFLAGSC "-"
1119#define MAX_FORMAT 32
1122static void addquoted (
luaL_Buffer *b,
const char *s,
size_t len) {
1123 luaL_addchar(b,
'"');
1125 if (*s ==
'"' || *s ==
'\\' || *s ==
'\n') {
1126 luaL_addchar(b,
'\\');
1127 luaL_addchar(b, *s);
1129 else if (iscntrl(uchar(*s))) {
1131 if (!isdigit(uchar(*(s+1))))
1132 l_sprintf(buff,
sizeof(buff),
"\\%d", (
int)uchar(*s));
1134 l_sprintf(buff,
sizeof(buff),
"\\%03d", (
int)uchar(*s));
1135 luaL_addstring(b, buff);
1138 luaL_addchar(b, *s);
1141 luaL_addchar(b,
'"');
1151static int quotefloat (
lua_State *L,
char *buff, lua_Number n) {
1153 if (n == (lua_Number)HUGE_VAL)
1155 else if (n == -(lua_Number)HUGE_VAL)
1160 int nb = lua_number2strx(L, buff, MAX_ITEM,
1161 "%" LUA_NUMBER_FRMLEN
"a", n);
1163 if (memchr(buff,
'.', nb) == NULL) {
1164 char point = lua_getlocaledecpoint();
1165 char *ppoint = (
char *)memchr(buff, point, nb);
1166 if (ppoint) *ppoint =
'.';
1171 return l_sprintf(buff, MAX_ITEM,
"%s", s);
1176 switch (lua_type(L, arg)) {
1179 const char *s = lua_tolstring(L, arg, &len);
1180 addquoted(b, s, len);
1184 char *buff = luaL_prepbuffsize(b, MAX_ITEM);
1186 if (!lua_isinteger(L, arg))
1187 nb = quotefloat(L, buff, lua_tonumber(L, arg));
1189 lua_Integer n = lua_tointeger(L, arg);
1190 const char *format = (n == LUA_MININTEGER)
1191 ?
"0x%" LUA_INTEGER_FRMLEN
"x"
1193 nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
1195 luaL_addsize(b, nb);
1198 case LUA_TNIL:
case LUA_TBOOLEAN: {
1199 luaL_tolstring(L, arg, NULL);
1204 luaL_argerror(L, arg,
"value has no literal form");
1210static const char *get2digits (
const char *s) {
1211 if (isdigit(uchar(*s))) {
1213 if (isdigit(uchar(*s))) s++;
1225static void checkformat (
lua_State *L,
const char *form,
const char *flags,
1227 const char *spec = form + 1;
1228 spec += strspn(spec, flags);
1230 spec = get2digits(spec);
1231 if (*spec ==
'.' && precision) {
1233 spec = get2digits(spec);
1236 if (!isalpha(uchar(*spec)))
1237 luaL_error(L,
"invalid conversion specification: '%s'", form);
1245static const char *getformat (
lua_State *L,
const char *strfrmt,
1248 size_t len = strspn(strfrmt, L_FMTFLAGSF
"123456789.");
1251 if (len >= MAX_FORMAT - 10)
1252 luaL_error(L,
"invalid format (too long)");
1254 memcpy(form, strfrmt, len *
sizeof(
char));
1255 *(form + len) =
'\0';
1256 return strfrmt + len - 1;
1263static void addlenmod (
char *form,
const char *lenmod) {
1264 size_t l = strlen(form);
1265 size_t lm = strlen(lenmod);
1266 char spec = form[l - 1];
1267 strcpy(form + l - 1, lenmod);
1268 form[l + lm - 1] = spec;
1269 form[l + lm] =
'\0';
1274 int top = lua_gettop(L);
1277 const char *strfrmt = luaL_checklstring(L, arg, &sfl);
1278 const char *strfrmt_end = strfrmt+sfl;
1281 luaL_buffinit(L, &b);
1282 while (strfrmt < strfrmt_end) {
1283 if (*strfrmt != L_ESC)
1284 luaL_addchar(&b, *strfrmt++);
1285 else if (*++strfrmt == L_ESC)
1286 luaL_addchar(&b, *strfrmt++);
1288 char form[MAX_FORMAT];
1289 int maxitem = MAX_ITEM;
1290 char *buff = luaL_prepbuffsize(&b, maxitem);
1293 return luaL_argerror(L, arg,
"no value");
1294 strfrmt = getformat(L, strfrmt, form);
1295 switch (*strfrmt++) {
1297 checkformat(L, form, L_FMTFLAGSC, 0);
1298 nb = l_sprintf(buff, maxitem, form, (
int)luaL_checkinteger(L, arg));
1302 flags = L_FMTFLAGSI;
1305 flags = L_FMTFLAGSU;
1307 case 'o':
case 'x':
case 'X':
1308 flags = L_FMTFLAGSX;
1310 lua_Integer n = luaL_checkinteger(L, arg);
1311 checkformat(L, form, flags, 1);
1312 addlenmod(form, LUA_INTEGER_FRMLEN);
1313 nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n);
1317 checkformat(L, form, L_FMTFLAGSF, 1);
1318 addlenmod(form, LUA_NUMBER_FRMLEN);
1319 nb = lua_number2strx(L, buff, maxitem, form,
1320 luaL_checknumber(L, arg));
1323 maxitem = MAX_ITEMF;
1324 buff = luaL_prepbuffsize(&b, maxitem);
1326 case 'e':
case 'E':
case 'g':
case 'G': {
1327 lua_Number n = luaL_checknumber(L, arg);
1328 checkformat(L, form, L_FMTFLAGSF, 1);
1329 addlenmod(form, LUA_NUMBER_FRMLEN);
1330 nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n);
1334 const void *p = lua_topointer(L, arg);
1335 checkformat(L, form, L_FMTFLAGSC, 0);
1338 form[strlen(form) - 1] =
's';
1340 nb = l_sprintf(buff, maxitem, form, p);
1344 if (form[2] !=
'\0')
1345 return luaL_error(L,
"specifier '%%q' cannot have modifiers");
1346 addliteral(L, &b, arg);
1351 const char *s = luaL_tolstring(L, arg, &l);
1352 if (form[2] ==
'\0')
1355 luaL_argcheck(L, l == strlen(s), arg,
"string contains zeros");
1356 checkformat(L, form, L_FMTFLAGSC, 1);
1357 if (strchr(form,
'.') == NULL && l >= 100) {
1362 nb = l_sprintf(buff, maxitem, form, s);
1369 return luaL_error(L,
"invalid conversion '%s' to 'format'", form);
1372 lua_assert(nb < maxitem);
1373 luaL_addsize(&b, nb);
1376 luaL_pushresult(&b);
1391#if !defined(LUAL_PACKPADBYTE)
1392#define LUAL_PACKPADBYTE 0x00
1396#define MAXINTSIZE 16
1402#define MC ((1 << NB) - 1)
1405#define SZINT ((int)sizeof(lua_Integer))
1412} nativeendian = {1};
1428typedef enum KOption {
1447static int digit (
int c) {
return '0' <= c && c <=
'9'; }
1449static int getnum (
const char **fmt,
int df) {
1455 a = a*10 + (*((*fmt)++) -
'0');
1456 }
while (digit(**fmt) && a <= ((
int)MAXSIZE - 9)/10);
1466static int getnumlimit (
Header *h,
const char **fmt,
int df) {
1467 int sz = getnum(fmt, df);
1468 if (l_unlikely(sz > MAXINTSIZE || sz <= 0))
1469 return luaL_error(h->L,
"integral size (%d) out of limits [1,%d]",
1480 h->islittle = nativeendian.little;
1488static KOption getoption (
Header *h,
const char **fmt,
int *size) {
1490 struct cD {
char c;
union { LUAI_MAXALIGN; } u; };
1491 int opt = *((*fmt)++);
1494 case 'b': *size =
sizeof(char);
return Kint;
1495 case 'B': *size =
sizeof(char);
return Kuint;
1496 case 'h': *size =
sizeof(short);
return Kint;
1497 case 'H': *size =
sizeof(short);
return Kuint;
1498 case 'l': *size =
sizeof(long);
return Kint;
1499 case 'L': *size =
sizeof(long);
return Kuint;
1500 case 'j': *size =
sizeof(lua_Integer);
return Kint;
1501 case 'J': *size =
sizeof(lua_Integer);
return Kuint;
1502 case 'T': *size =
sizeof(size_t);
return Kuint;
1503 case 'f': *size =
sizeof(float);
return Kfloat;
1504 case 'n': *size =
sizeof(lua_Number);
return Knumber;
1505 case 'd': *size =
sizeof(double);
return Kdouble;
1506 case 'i': *size = getnumlimit(h, fmt,
sizeof(
int));
return Kint;
1507 case 'I': *size = getnumlimit(h, fmt,
sizeof(
int));
return Kuint;
1508 case 's': *size = getnumlimit(h, fmt,
sizeof(
size_t));
return Kstring;
1510 *size = getnum(fmt, -1);
1511 if (l_unlikely(*size == -1))
1512 luaL_error(h->L,
"missing size for format option 'c'");
1514 case 'z':
return Kzstr;
1515 case 'x': *size = 1;
return Kpadding;
1516 case 'X':
return Kpaddalign;
1518 case '<': h->islittle = 1;
break;
1519 case '>': h->islittle = 0;
break;
1520 case '=': h->islittle = nativeendian.little;
break;
1522 const int maxalign = offsetof(
struct cD, u);
1523 h->maxalign = getnumlimit(h, fmt, maxalign);
1526 default: luaL_error(h->L,
"invalid format option '%c'", opt);
1541static KOption getdetails (
Header *h,
size_t totalsize,
1542 const char **fmt,
int *psize,
int *ntoalign) {
1543 KOption opt = getoption(h, fmt, psize);
1545 if (opt == Kpaddalign) {
1546 if (**fmt ==
'\0' || getoption(h, fmt, &align) == Kchar || align == 0)
1547 luaL_argerror(h->L, 1,
"invalid next option for option 'X'");
1549 if (align <= 1 || opt == Kchar)
1552 if (align > h->maxalign)
1553 align = h->maxalign;
1554 if (l_unlikely((align & (align - 1)) != 0))
1555 luaL_argerror(h->L, 1,
"format asks for alignment not power of 2");
1556 *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
1568static void packint (
luaL_Buffer *b, lua_Unsigned n,
1569 int islittle,
int size,
int neg) {
1570 char *buff = luaL_prepbuffsize(b, size);
1572 buff[islittle ? 0 : size - 1] = (char)(n & MC);
1573 for (i = 1; i < size; i++) {
1575 buff[islittle ? i : size - 1 - i] = (char)(n & MC);
1577 if (neg && size > SZINT) {
1578 for (i = SZINT; i < size; i++)
1579 buff[islittle ? i : size - 1 - i] = (char)MC;
1581 luaL_addsize(b, size);
1589static void copywithendian (
char *dest,
const char *src,
1590 int size,
int islittle) {
1591 if (islittle == nativeendian.little)
1592 memcpy(dest, src, size);
1596 *(dest--) = *(src++);
1604 const char *fmt = luaL_checkstring(L, 1);
1606 size_t totalsize = 0;
1609 luaL_buffinit(L, &b);
1610 while (*fmt !=
'\0') {
1612 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1613 totalsize += ntoalign + size;
1614 while (ntoalign-- > 0)
1615 luaL_addchar(&b, LUAL_PACKPADBYTE);
1619 lua_Integer n = luaL_checkinteger(L, arg);
1621 lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1);
1622 luaL_argcheck(L, -lim <= n && n < lim, arg,
"integer overflow");
1624 packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0));
1628 lua_Integer n = luaL_checkinteger(L, arg);
1630 luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)),
1631 arg,
"unsigned overflow");
1632 packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
1636 float f = (float)luaL_checknumber(L, arg);
1637 char *buff = luaL_prepbuffsize(&b,
sizeof(f));
1639 copywithendian(buff, (
char *)&f,
sizeof(f), h.islittle);
1640 luaL_addsize(&b, size);
1644 lua_Number f = luaL_checknumber(L, arg);
1645 char *buff = luaL_prepbuffsize(&b,
sizeof(f));
1647 copywithendian(buff, (
char *)&f,
sizeof(f), h.islittle);
1648 luaL_addsize(&b, size);
1652 double f = (double)luaL_checknumber(L, arg);
1653 char *buff = luaL_prepbuffsize(&b,
sizeof(f));
1655 copywithendian(buff, (
char *)&f,
sizeof(f), h.islittle);
1656 luaL_addsize(&b, size);
1661 const char *s = luaL_checklstring(L, arg, &len);
1662 luaL_argcheck(L, len <= (
size_t)size, arg,
1663 "string longer than given size");
1664 luaL_addlstring(&b, s, len);
1665 while (len++ < (
size_t)size)
1666 luaL_addchar(&b, LUAL_PACKPADBYTE);
1671 const char *s = luaL_checklstring(L, arg, &len);
1672 luaL_argcheck(L, size >= (
int)
sizeof(
size_t) ||
1673 len < ((
size_t)1 << (size * NB)),
1674 arg,
"string length does not fit in given size");
1675 packint(&b, (lua_Unsigned)len, h.islittle, size, 0);
1676 luaL_addlstring(&b, s, len);
1682 const char *s = luaL_checklstring(L, arg, &len);
1683 luaL_argcheck(L, strlen(s) == len, arg,
"string contains zeros");
1684 luaL_addlstring(&b, s, len);
1685 luaL_addchar(&b,
'\0');
1686 totalsize += len + 1;
1689 case Kpadding: luaL_addchar(&b, LUAL_PACKPADBYTE);
1690 case Kpaddalign:
case Knop:
1695 luaL_pushresult(&b);
1702 const char *fmt = luaL_checkstring(L, 1);
1703 size_t totalsize = 0;
1705 while (*fmt !=
'\0') {
1707 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1708 luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1,
1709 "variable-length format");
1711 luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
1712 "format result too large");
1715 lua_pushinteger(L, (lua_Integer)totalsize);
1728static lua_Integer unpackint (
lua_State *L,
const char *str,
1729 int islittle,
int size,
int issigned) {
1730 lua_Unsigned res = 0;
1732 int limit = (size <= SZINT) ? size : SZINT;
1733 for (i = limit - 1; i >= 0; i--) {
1735 res |= (lua_Unsigned)(
unsigned char)str[islittle ? i : size - 1 - i];
1739 lua_Unsigned mask = (lua_Unsigned)1 << (size*NB - 1);
1740 res = ((res ^ mask) - mask);
1743 else if (size > SZINT) {
1744 int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC;
1745 for (i = limit; i < size; i++) {
1746 if (l_unlikely((
unsigned char)str[islittle ? i : size - 1 - i] != mask))
1747 luaL_error(L,
"%d-byte integer does not fit into Lua Integer", size);
1750 return (lua_Integer)res;
1756 const char *fmt = luaL_checkstring(L, 1);
1758 const char *data = luaL_checklstring(L, 2, &ld);
1759 size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1;
1761 luaL_argcheck(L, pos <= ld, 3,
"initial position out of string");
1763 while (*fmt !=
'\0') {
1765 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
1766 luaL_argcheck(L, (
size_t)ntoalign + size <= ld - pos, 2,
1767 "data string too short");
1770 luaL_checkstack(L, 2,
"too many results");
1775 lua_Integer res = unpackint(L, data + pos, h.islittle, size,
1777 lua_pushinteger(L, res);
1782 copywithendian((
char *)&f, data + pos,
sizeof(f), h.islittle);
1783 lua_pushnumber(L, (lua_Number)f);
1788 copywithendian((
char *)&f, data + pos,
sizeof(f), h.islittle);
1789 lua_pushnumber(L, f);
1794 copywithendian((
char *)&f, data + pos,
sizeof(f), h.islittle);
1795 lua_pushnumber(L, (lua_Number)f);
1799 lua_pushlstring(L, data + pos, size);
1803 size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
1804 luaL_argcheck(L, len <= ld - pos - size, 2,
"data string too short");
1805 lua_pushlstring(L, data + pos + size, len);
1810 size_t len = strlen(data + pos);
1811 luaL_argcheck(L, pos + len < ld, 2,
1812 "unfinished string for format 'z'");
1813 lua_pushlstring(L, data + pos, len);
1817 case Kpaddalign:
case Kpadding:
case Knop:
1823 lua_pushinteger(L, pos + 1);
1835 {
"format", str_format},
1839 {
"lower", str_lower},
1840 {
"match", str_match},
1842 {
"reverse", str_reverse},
1844 {
"upper", str_upper},
1846 {
"packsize", str_packsize},
1847 {
"unpack", str_unpack},
1852static void createmetatable (
lua_State *L) {
1854 luaL_newlibtable(L, stringmetamethods);
1855 luaL_setfuncs(L, stringmetamethods, 0);
1856 lua_pushliteral(L,
"");
1857 lua_pushvalue(L, -2);
1858 lua_setmetatable(L, -2);
1860 lua_pushvalue(L, -2);
1861 lua_setfield(L, -2,
"__index");
1869LUAMOD_API
int luaopen_string (
lua_State *L) {
1870 luaL_newlib(L, strlib);