Merge pull request #2672 from kitsunehunter/laundry-keys
[RRG-proxmark3.git] / client / deps / liblua / lstrlib.c
blob56d88ea99d44ad31f38973021c234f26b05519a6
1 /*
2 ** $Id: lstrlib.c $
3 ** Standard library for string operations and pattern-matching
4 ** See Copyright Notice in lua.h
5 */
7 #define lstrlib_c
8 #define LUA_LIB
10 #include "lprefix.h"
13 #include <ctype.h>
14 #include <float.h>
15 #include <limits.h>
16 #include <locale.h>
17 #include <math.h>
18 #include <stddef.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
23 #include "lua.h"
25 #include "lauxlib.h"
26 #include "lualib.h"
30 ** maximum number of captures that a pattern can do during
31 ** pattern-matching. This limit is arbitrary, but must fit in
32 ** an unsigned char.
34 #if !defined(LUA_MAXCAPTURES)
35 #define LUA_MAXCAPTURES 32
36 #endif
39 /* macro to 'unsign' a character */
40 #define uchar(c) ((unsigned char)(c))
44 ** Some sizes are better limited to fit in 'int', but must also fit in
45 ** 'size_t'. (We assume that 'lua_Integer' cannot be smaller than 'int'.)
47 #define MAX_SIZET ((size_t)(~(size_t)0))
49 #define MAXSIZE \
50 (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
55 static int str_len(lua_State *L) {
56 size_t l;
57 luaL_checklstring(L, 1, &l);
58 lua_pushinteger(L, (lua_Integer)l);
59 return 1;
64 ** translate a relative initial string position
65 ** (negative means back from end): clip result to [1, inf).
66 ** The length of any string in Lua must fit in a lua_Integer,
67 ** so there are no overflows in the casts.
68 ** The inverted comparison avoids a possible overflow
69 ** computing '-pos'.
71 static size_t posrelatI(lua_Integer pos, size_t len) {
72 if (pos > 0)
73 return (size_t)pos;
74 else if (pos == 0)
75 return 1;
76 else if (pos < -(lua_Integer)len) /* inverted comparison */
77 return 1; /* clip to 1 */
78 else return len + (size_t)pos + 1;
83 ** Gets an optional ending string position from argument 'arg',
84 ** with default value 'def'.
85 ** Negative means back from end: clip result to [0, len]
87 static size_t getendpos(lua_State *L, int arg, lua_Integer def,
88 size_t len) {
89 lua_Integer pos = luaL_optinteger(L, arg, def);
90 if (pos > (lua_Integer)len)
91 return len;
92 else if (pos >= 0)
93 return (size_t)pos;
94 else if (pos < -(lua_Integer)len)
95 return 0;
96 else return len + (size_t)pos + 1;
100 static int str_sub(lua_State *L) {
101 size_t l;
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);
105 if (start <= end)
106 lua_pushlstring(L, s + start - 1, (end - start) + 1);
107 else lua_pushliteral(L, "");
108 return 1;
112 static int str_reverse(lua_State *L) {
113 size_t l, i;
114 luaL_Buffer b;
115 const char *s = luaL_checklstring(L, 1, &l);
116 char *p = luaL_buffinitsize(L, &b, l);
117 for (i = 0; i < l; i++)
118 p[i] = s[l - i - 1];
119 luaL_pushresultsize(&b, l);
120 return 1;
124 static int str_lower(lua_State *L) {
125 size_t l;
126 size_t i;
127 luaL_Buffer b;
128 const char *s = luaL_checklstring(L, 1, &l);
129 char *p = luaL_buffinitsize(L, &b, l);
130 for (i = 0; i < l; i++)
131 p[i] = tolower(uchar(s[i]));
132 luaL_pushresultsize(&b, l);
133 return 1;
137 static int str_upper(lua_State *L) {
138 size_t l;
139 size_t i;
140 luaL_Buffer b;
141 const char *s = luaL_checklstring(L, 1, &l);
142 char *p = luaL_buffinitsize(L, &b, l);
143 for (i = 0; i < l; i++)
144 p[i] = toupper(uchar(s[i]));
145 luaL_pushresultsize(&b, l);
146 return 1;
150 static int str_rep(lua_State *L) {
151 size_t l, lsep;
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);
155 if (n <= 0)
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");
159 else {
160 size_t totallen = (size_t)n * l + (size_t)(n - 1) * lsep;
161 luaL_Buffer b;
162 char *p = luaL_buffinitsize(L, &b, totallen);
163 while (n-- > 1) { /* first n-1 copies (followed by separator) */
164 memcpy(p, s, l * sizeof(char));
165 p += l;
166 if (lsep > 0) { /* empty 'memcpy' is not that cheap */
167 memcpy(p, sep, lsep * sizeof(char));
168 p += lsep;
171 memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */
172 luaL_pushresultsize(&b, totallen);
174 return 1;
178 static int str_byte(lua_State *L) {
179 size_t l;
180 const char *s = luaL_checklstring(L, 1, &l);
181 lua_Integer pi = luaL_optinteger(L, 2, 1);
182 size_t posi = posrelatI(pi, l);
183 size_t pose = getendpos(L, 3, pi, l);
184 int n, i;
185 if (posi > pose) return 0; /* empty interval; return no values */
186 if (l_unlikely(pose - posi >= (size_t)INT_MAX)) /* arithmetic overflow? */
187 return luaL_error(L, "string slice too long");
188 n = (int)(pose - posi) + 1;
189 luaL_checkstack(L, n, "string slice too long");
190 for (i = 0; i < n; i++)
191 lua_pushinteger(L, uchar(s[posi + i - 1]));
192 return n;
196 static int str_char(lua_State *L) {
197 int n = lua_gettop(L); /* number of arguments */
198 int i;
199 luaL_Buffer b;
200 char *p = luaL_buffinitsize(L, &b, n);
201 for (i = 1; i <= n; i++) {
202 lua_Unsigned c = (lua_Unsigned)luaL_checkinteger(L, i);
203 luaL_argcheck(L, c <= (lua_Unsigned)UCHAR_MAX, i, "value out of range");
204 p[i - 1] = uchar(c);
206 luaL_pushresultsize(&b, n);
207 return 1;
212 ** Buffer to store the result of 'string.dump'. It must be initialized
213 ** after the call to 'lua_dump', to ensure that the function is on the
214 ** top of the stack when 'lua_dump' is called. ('luaL_buffinit' might
215 ** push stuff.)
217 struct str_Writer {
218 int init; /* true iff buffer has been initialized */
219 luaL_Buffer B;
223 static int writer(lua_State *L, const void *b, size_t size, void *ud) {
224 struct str_Writer *state = (struct str_Writer *)ud;
225 if (!state->init) {
226 state->init = 1;
227 luaL_buffinit(L, &state->B);
229 luaL_addlstring(&state->B, (const char *)b, size);
230 return 0;
234 static int str_dump(lua_State *L) {
235 struct str_Writer state;
236 int strip = lua_toboolean(L, 2);
237 luaL_checktype(L, 1, LUA_TFUNCTION);
238 lua_settop(L, 1); /* ensure function is on the top of the stack */
239 state.init = 0;
240 if (l_unlikely(lua_dump(L, writer, &state, strip) != 0))
241 return luaL_error(L, "unable to dump given function");
242 luaL_pushresult(&state.B);
243 return 1;
249 ** {======================================================
250 ** METAMETHODS
251 ** =======================================================
254 #if defined(LUA_NOCVTS2N) /* { */
256 /* no coercion from strings to numbers */
258 static const luaL_Reg stringmetamethods[] = {
259 {"__index", NULL}, /* placeholder */
260 {NULL, NULL}
263 #else /* }{ */
265 static int tonum(lua_State *L, int arg) {
266 if (lua_type(L, arg) == LUA_TNUMBER) { /* already a number? */
267 lua_pushvalue(L, arg);
268 return 1;
269 } else { /* check whether it is a numerical string */
270 size_t len;
271 const char *s = lua_tolstring(L, arg, &len);
272 return (s != NULL && lua_stringtonumber(L, s) == len + 1);
277 static void trymt(lua_State *L, const char *mtname) {
278 lua_settop(L, 2); /* back to the original arguments */
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));
283 lua_insert(L, -3); /* put metamethod before arguments */
284 lua_call(L, 2, 1); /* call metamethod */
288 static int arith(lua_State *L, int op, const char *mtname) {
289 if (tonum(L, 1) && tonum(L, 2))
290 lua_arith(L, op); /* result will be on the top */
291 else
292 trymt(L, mtname);
293 return 1;
297 static int arith_add(lua_State *L) {
298 return arith(L, LUA_OPADD, "__add");
301 static int arith_sub(lua_State *L) {
302 return arith(L, LUA_OPSUB, "__sub");
305 static int arith_mul(lua_State *L) {
306 return arith(L, LUA_OPMUL, "__mul");
309 static int arith_mod(lua_State *L) {
310 return arith(L, LUA_OPMOD, "__mod");
313 static int arith_pow(lua_State *L) {
314 return arith(L, LUA_OPPOW, "__pow");
317 static int arith_div(lua_State *L) {
318 return arith(L, LUA_OPDIV, "__div");
321 static int arith_idiv(lua_State *L) {
322 return arith(L, LUA_OPIDIV, "__idiv");
325 static int arith_unm(lua_State *L) {
326 return arith(L, LUA_OPUNM, "__unm");
330 static 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},
339 {"__index", NULL}, /* placeholder */
340 {NULL, NULL}
343 #endif /* } */
345 /* }====================================================== */
348 ** {======================================================
349 ** PATTERN MATCHING
350 ** =======================================================
354 #define CAP_UNFINISHED (-1)
355 #define CAP_POSITION (-2)
358 typedef struct MatchState {
359 const char *src_init; /* init of source string */
360 const char *src_end; /* end ('\0') of source string */
361 const char *p_end; /* end ('\0') of pattern */
362 lua_State *L;
363 int matchdepth; /* control for recursive depth (to avoid C stack overflow) */
364 unsigned char level; /* total number of captures (finished or unfinished) */
365 struct {
366 const char *init;
367 ptrdiff_t len;
368 } capture[LUA_MAXCAPTURES];
369 } MatchState;
372 /* recursive function */
373 static const char *match(MatchState *ms, const char *s, const char *p);
376 /* maximum recursion depth for 'match' */
377 #if !defined(MAXCCALLS)
378 #define MAXCCALLS 200
379 #endif
382 #define L_ESC '%'
383 #define SPECIALS "^$*+?.([%-"
386 static int check_capture(MatchState *ms, int l) {
387 l -= '1';
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);
391 return l;
395 static int capture_to_close(MatchState *ms) {
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");
403 static const char *classend(MatchState *ms, const char *p) {
404 switch (*p++) {
405 case L_ESC: {
406 if (l_unlikely(p == ms->p_end))
407 luaL_error(ms->L, "malformed pattern (ends with '%%')");
408 return p + 1;
410 case '[': {
411 if (*p == '^') p++;
412 do { /* look for a ']' */
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)
416 p++; /* skip escapes (e.g. '%]') */
417 } while (*p != ']');
418 return p + 1;
420 default: {
421 return p;
427 static int match_class(int c, int cl) {
428 int res;
429 switch (tolower(cl)) {
430 case 'a' :
431 res = isalpha(c);
432 break;
433 case 'c' :
434 res = iscntrl(c);
435 break;
436 case 'd' :
437 res = isdigit(c);
438 break;
439 case 'g' :
440 res = isgraph(c);
441 break;
442 case 'l' :
443 res = islower(c);
444 break;
445 case 'p' :
446 res = ispunct(c);
447 break;
448 case 's' :
449 res = isspace(c);
450 break;
451 case 'u' :
452 res = isupper(c);
453 break;
454 case 'w' :
455 res = isalnum(c);
456 break;
457 case 'x' :
458 res = isxdigit(c);
459 break;
460 case 'z' :
461 res = (c == 0);
462 break; /* deprecated option */
463 default:
464 return (cl == c);
466 return (islower(cl) ? res : !res);
470 static int matchbracketclass(int c, const char *p, const char *ec) {
471 int sig = 1;
472 if (*(p + 1) == '^') {
473 sig = 0;
474 p++; /* skip the '^' */
476 while (++p < ec) {
477 if (*p == L_ESC) {
478 p++;
479 if (match_class(c, uchar(*p)))
480 return sig;
481 } else if ((*(p + 1) == '-') && (p + 2 < ec)) {
482 p += 2;
483 if (uchar(*(p - 2)) <= c && c <= uchar(*p))
484 return sig;
485 } else if (uchar(*p) == c) return sig;
487 return !sig;
491 static int singlematch(MatchState *ms, const char *s, const char *p,
492 const char *ep) {
493 if (s >= ms->src_end)
494 return 0;
495 else {
496 int c = uchar(*s);
497 switch (*p) {
498 case '.':
499 return 1; /* matches any char */
500 case L_ESC:
501 return match_class(c, uchar(*(p + 1)));
502 case '[':
503 return matchbracketclass(c, p, ep - 1);
504 default:
505 return (uchar(*p) == c);
511 static const char *matchbalance(MatchState *ms, const char *s,
512 const char *p) {
513 if (l_unlikely(p >= ms->p_end - 1))
514 luaL_error(ms->L, "malformed pattern (missing arguments to '%%b')");
515 if (*s != *p) return NULL;
516 else {
517 int b = *p;
518 int e = *(p + 1);
519 int cont = 1;
520 while (++s < ms->src_end) {
521 if (*s == e) {
522 if (--cont == 0) return s + 1;
523 } else if (*s == b) cont++;
526 return NULL; /* string ends out of balance */
530 static const char *max_expand(MatchState *ms, const char *s,
531 const char *p, const char *ep) {
532 ptrdiff_t i = 0; /* counts maximum expand for item */
533 while (singlematch(ms, s + i, p, ep))
534 i++;
535 /* keeps trying to match with the maximum repetitions */
536 while (i >= 0) {
537 const char *res = match(ms, (s + i), ep + 1);
538 if (res) return res;
539 i--; /* else didn't match; reduce 1 repetition to try again */
541 return NULL;
545 static const char *min_expand(MatchState *ms, const char *s,
546 const char *p, const char *ep) {
547 for (;;) {
548 const char *res = match(ms, s, ep + 1);
549 if (res != NULL)
550 return res;
551 else if (singlematch(ms, s, p, ep))
552 s++; /* try with one more repetition */
553 else return NULL;
558 static const char *start_capture(MatchState *ms, const char *s,
559 const char *p, int what) {
560 const char *res;
561 int level = ms->level;
562 if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
563 ms->capture[level].init = s;
564 ms->capture[level].len = what;
565 ms->level = level + 1;
566 if ((res = match(ms, s, p)) == NULL) /* match failed? */
567 ms->level--; /* undo capture */
568 return res;
572 static const char *end_capture(MatchState *ms, const char *s,
573 const char *p) {
574 int l = capture_to_close(ms);
575 const char *res;
576 ms->capture[l].len = s - ms->capture[l].init; /* close capture */
577 if ((res = match(ms, s, p)) == NULL) /* match failed? */
578 ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
579 return res;
583 static const char *match_capture(MatchState *ms, const char *s, int l) {
584 size_t len;
585 l = check_capture(ms, l);
586 len = ms->capture[l].len;
587 if ((size_t)(ms->src_end - s) >= len &&
588 memcmp(ms->capture[l].init, s, len) == 0)
589 return s + len;
590 else return NULL;
594 static const char *match(MatchState *ms, const char *s, const char *p) {
595 if (l_unlikely(ms->matchdepth-- == 0))
596 luaL_error(ms->L, "pattern too complex");
597 init: /* using goto to optimize tail recursion */
598 if (p != ms->p_end) { /* end of pattern? */
599 switch (*p) {
600 case '(': { /* start capture */
601 if (*(p + 1) == ')') /* position capture? */
602 s = start_capture(ms, s, p + 2, CAP_POSITION);
603 else
604 s = start_capture(ms, s, p + 1, CAP_UNFINISHED);
605 break;
607 case ')': { /* end capture */
608 s = end_capture(ms, s, p + 1);
609 break;
611 case '$': {
612 if ((p + 1) != ms->p_end) /* is the '$' the last char in pattern? */
613 goto dflt; /* no; go to default */
614 s = (s == ms->src_end) ? s : NULL; /* check end of string */
615 break;
617 case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
618 switch (*(p + 1)) {
619 case 'b': { /* balanced string? */
620 s = matchbalance(ms, s, p + 2);
621 if (s != NULL) {
622 p += 4;
623 goto init; /* return match(ms, s, p + 4); */
624 } /* else fail (s == NULL) */
625 break;
627 case 'f': { /* frontier? */
628 const char *ep;
629 char previous;
630 p += 2;
631 if (l_unlikely(*p != '['))
632 luaL_error(ms->L, "missing '[' after '%%f' in pattern");
633 ep = classend(ms, p); /* points to what is next */
634 previous = (s == ms->src_init) ? '\0' : *(s - 1);
635 if (!matchbracketclass(uchar(previous), p, ep - 1) &&
636 matchbracketclass(uchar(*s), p, ep - 1)) {
637 p = ep;
638 goto init; /* return match(ms, s, ep); */
640 s = NULL; /* match failed */
641 break;
643 case '0':
644 case '1':
645 case '2':
646 case '3':
647 case '4':
648 case '5':
649 case '6':
650 case '7':
651 case '8':
652 case '9': { /* capture results (%0-%9)? */
653 s = match_capture(ms, s, uchar(*(p + 1)));
654 if (s != NULL) {
655 p += 2;
656 goto init; /* return match(ms, s, p + 2) */
658 break;
660 default:
661 goto dflt;
663 break;
665 default:
666 dflt: { /* pattern class plus optional suffix */
667 const char *ep = classend(ms, p); /* points to optional suffix */
668 /* does not match at least once? */
669 if (!singlematch(ms, s, p, ep)) {
670 if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */
671 p = ep + 1;
672 goto init; /* return match(ms, s, ep + 1); */
673 } else /* '+' or no suffix */
674 s = NULL; /* fail */
675 } else { /* matched once */
676 switch (*ep) { /* handle optional suffix */
677 case '?': { /* optional */
678 const char *res;
679 if ((res = match(ms, s + 1, ep + 1)) != NULL)
680 s = res;
681 else {
682 p = ep + 1;
683 goto init; /* else return match(ms, s, ep + 1); */
685 break;
687 case '+': /* 1 or more repetitions */
688 s++; /* 1 match already done */
689 /* FALLTHROUGH */
690 case '*': /* 0 or more repetitions */
691 s = max_expand(ms, s, p, ep);
692 break;
693 case '-': /* 0 or more repetitions (minimum) */
694 s = min_expand(ms, s, p, ep);
695 break;
696 default: /* no suffix */
697 s++;
698 p = ep;
699 goto init; /* return match(ms, s + 1, ep); */
702 break;
706 ms->matchdepth++;
707 return s;
712 static const char *lmemfind(const char *s1, size_t l1,
713 const char *s2, size_t l2) {
714 if (l2 == 0) return s1; /* empty strings are everywhere */
715 else if (l2 > l1) return NULL; /* avoids a negative 'l1' */
716 else {
717 const char *init; /* to search for a '*s2' inside 's1' */
718 l2--; /* 1st char will be checked by 'memchr' */
719 l1 = l1 - l2; /* 's2' cannot be found after that */
720 while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
721 init++; /* 1st char is already checked */
722 if (memcmp(init, s2 + 1, l2) == 0)
723 return init - 1;
724 else { /* correct 'l1' and 's1' to try again */
725 l1 -= init - s1;
726 s1 = init;
729 return NULL; /* not found */
735 ** get information about the i-th capture. If there are no captures
736 ** and 'i==0', return information about the whole match, which
737 ** is the range 's'..'e'. If the capture is a string, return
738 ** its length and put its address in '*cap'. If it is an integer
739 ** (a position), push it on the stack and return CAP_POSITION.
741 static size_t get_onecapture(MatchState *ms, int i, const char *s,
742 const char *e, const char **cap) {
743 if (i >= ms->level) {
744 if (l_unlikely(i != 0))
745 luaL_error(ms->L, "invalid capture index %%%d", i + 1);
746 *cap = s;
747 return e - s;
748 } else {
749 ptrdiff_t capl = ms->capture[i].len;
750 *cap = ms->capture[i].init;
751 if (l_unlikely(capl == CAP_UNFINISHED))
752 luaL_error(ms->L, "unfinished capture");
753 else if (capl == CAP_POSITION)
754 lua_pushinteger(ms->L, (ms->capture[i].init - ms->src_init) + 1);
755 return capl;
761 ** Push the i-th capture on the stack.
763 static void push_onecapture(MatchState *ms, int i, const char *s,
764 const char *e) {
765 const char *cap;
766 ptrdiff_t l = get_onecapture(ms, i, s, e, &cap);
767 if (l != CAP_POSITION)
768 lua_pushlstring(ms->L, cap, l);
769 /* else position was already pushed */
773 static int push_captures(MatchState *ms, const char *s, const char *e) {
774 int i;
775 int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
776 luaL_checkstack(ms->L, nlevels, "too many captures");
777 for (i = 0; i < nlevels; i++)
778 push_onecapture(ms, i, s, e);
779 return nlevels; /* number of strings pushed */
783 /* check whether pattern has no special characters */
784 static int nospecials(const char *p, size_t l) {
785 size_t upto = 0;
786 do {
787 if (strpbrk(p + upto, SPECIALS))
788 return 0; /* pattern has a special character */
789 upto += strlen(p + upto) + 1; /* may have more after \0 */
790 } while (upto <= l);
791 return 1; /* no special chars found */
795 static void prepstate(MatchState *ms, lua_State *L,
796 const char *s, size_t ls, const char *p, size_t lp) {
797 ms->L = L;
798 ms->matchdepth = MAXCCALLS;
799 ms->src_init = s;
800 ms->src_end = s + ls;
801 ms->p_end = p + lp;
805 static void reprepstate(MatchState *ms) {
806 ms->level = 0;
807 lua_assert(ms->matchdepth == MAXCCALLS);
811 static int str_find_aux(lua_State *L, int find) {
812 size_t ls, lp;
813 const char *s = luaL_checklstring(L, 1, &ls);
814 const char *p = luaL_checklstring(L, 2, &lp);
815 size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1;
816 if (init > ls) { /* start after string's end? */
817 luaL_pushfail(L); /* cannot find anything */
818 return 1;
820 /* explicit request or no special characters? */
821 if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
822 /* do a plain search */
823 const char *s2 = lmemfind(s + init, ls - init, p, lp);
824 if (s2) {
825 lua_pushinteger(L, (s2 - s) + 1);
826 lua_pushinteger(L, (s2 - s) + lp);
827 return 2;
829 } else {
830 MatchState ms;
831 const char *s1 = s + init;
832 int anchor = (*p == '^');
833 if (anchor) {
834 p++;
835 lp--; /* skip anchor character */
837 prepstate(&ms, L, s, ls, p, lp);
838 do {
839 const char *res;
840 reprepstate(&ms);
841 if ((res = match(&ms, s1, p)) != NULL) {
842 if (find) {
843 lua_pushinteger(L, (s1 - s) + 1); /* start */
844 lua_pushinteger(L, res - s); /* end */
845 return push_captures(&ms, NULL, 0) + 2;
846 } else
847 return push_captures(&ms, s1, res);
849 } while (s1++ < ms.src_end && !anchor);
851 luaL_pushfail(L); /* not found */
852 return 1;
856 static int str_find(lua_State *L) {
857 return str_find_aux(L, 1);
861 static int str_match(lua_State *L) {
862 return str_find_aux(L, 0);
866 /* state for 'gmatch' */
867 typedef struct GMatchState {
868 const char *src; /* current position */
869 const char *p; /* pattern */
870 const char *lastmatch; /* end of last match */
871 MatchState ms; /* match state */
872 } GMatchState;
875 static int gmatch_aux(lua_State *L) {
876 GMatchState *gm = (GMatchState *)lua_touserdata(L, lua_upvalueindex(3));
877 const char *src;
878 gm->ms.L = L;
879 for (src = gm->src; src <= gm->ms.src_end; src++) {
880 const char *e;
881 reprepstate(&gm->ms);
882 if ((e = match(&gm->ms, src, gm->p)) != NULL && e != gm->lastmatch) {
883 gm->src = gm->lastmatch = e;
884 return push_captures(&gm->ms, src, e);
887 return 0; /* not found */
891 static int gmatch(lua_State *L) {
892 size_t ls, lp;
893 const char *s = luaL_checklstring(L, 1, &ls);
894 const char *p = luaL_checklstring(L, 2, &lp);
895 size_t init = posrelatI(luaL_optinteger(L, 3, 1), ls) - 1;
896 GMatchState *gm;
897 lua_settop(L, 2); /* keep strings on closure to avoid being collected */
898 gm = (GMatchState *)lua_newuserdatauv(L, sizeof(GMatchState), 0);
899 if (init > ls) /* start after string's end? */
900 init = ls + 1; /* avoid overflows in 's + init' */
901 prepstate(&gm->ms, L, s, ls, p, lp);
902 gm->src = s + init;
903 gm->p = p;
904 gm->lastmatch = NULL;
905 lua_pushcclosure(L, gmatch_aux, 3);
906 return 1;
910 static void add_s(MatchState *ms, luaL_Buffer *b, const char *s,
911 const char *e) {
912 size_t l;
913 lua_State *L = ms->L;
914 const char *news = lua_tolstring(L, 3, &l);
915 const char *p;
916 while ((p = (char *)memchr(news, L_ESC, l)) != NULL) {
917 luaL_addlstring(b, news, p - news);
918 p++; /* skip ESC */
919 if (*p == L_ESC) /* '%%' */
920 luaL_addchar(b, *p);
921 else if (*p == '0') /* '%0' */
922 luaL_addlstring(b, s, e - s);
923 else if (isdigit(uchar(*p))) { /* '%n' */
924 const char *cap;
925 ptrdiff_t resl = get_onecapture(ms, *p - '1', s, e, &cap);
926 if (resl == CAP_POSITION)
927 luaL_addvalue(b); /* add position to accumulated result */
928 else
929 luaL_addlstring(b, cap, resl);
930 } else
931 luaL_error(L, "invalid use of '%c' in replacement string", L_ESC);
932 l -= p + 1 - news;
933 news = p + 1;
935 luaL_addlstring(b, news, l);
940 ** Add the replacement value to the string buffer 'b'.
941 ** Return true if the original string was changed. (Function calls and
942 ** table indexing resulting in nil or false do not change the subject.)
944 static int add_value(MatchState *ms, luaL_Buffer *b, const char *s,
945 const char *e, int tr) {
946 lua_State *L = ms->L;
947 switch (tr) {
948 case LUA_TFUNCTION: { /* call the function */
949 int n;
950 lua_pushvalue(L, 3); /* push the function */
951 n = push_captures(ms, s, e); /* all captures as arguments */
952 lua_call(L, n, 1); /* call it */
953 break;
955 case LUA_TTABLE: { /* index the table */
956 push_onecapture(ms, 0, s, e); /* first capture is the index */
957 lua_gettable(L, 3);
958 break;
960 default: { /* LUA_TNUMBER or LUA_TSTRING */
961 add_s(ms, b, s, e); /* add value to the buffer */
962 return 1; /* something changed */
965 if (!lua_toboolean(L, -1)) { /* nil or false? */
966 lua_pop(L, 1); /* remove value */
967 luaL_addlstring(b, s, e - s); /* keep original text */
968 return 0; /* no changes */
969 } else if (l_unlikely(!lua_isstring(L, -1)))
970 return luaL_error(L, "invalid replacement value (a %s)",
971 luaL_typename(L, -1));
972 else {
973 luaL_addvalue(b); /* add result to accumulator */
974 return 1; /* something changed */
979 static int str_gsub(lua_State *L) {
980 size_t srcl, lp;
981 const char *src = luaL_checklstring(L, 1, &srcl); /* subject */
982 const char *p = luaL_checklstring(L, 2, &lp); /* pattern */
983 const char *lastmatch = NULL; /* end of last match */
984 int tr = lua_type(L, 3); /* replacement type */
985 lua_Integer max_s = luaL_optinteger(L, 4, srcl + 1); /* max replacements */
986 int anchor = (*p == '^');
987 lua_Integer n = 0; /* replacement count */
988 int changed = 0; /* change flag */
989 MatchState ms;
990 luaL_Buffer b;
991 luaL_argexpected(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
992 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
993 "string/function/table");
994 luaL_buffinit(L, &b);
995 if (anchor) {
996 p++;
997 lp--; /* skip anchor character */
999 prepstate(&ms, L, src, srcl, p, lp);
1000 while (n < max_s) {
1001 const char *e;
1002 reprepstate(&ms); /* (re)prepare state for new match */
1003 if ((e = match(&ms, src, p)) != NULL && e != lastmatch) { /* match? */
1004 n++;
1005 changed = add_value(&ms, &b, src, e, tr) | changed;
1006 src = lastmatch = e;
1007 } else if (src < ms.src_end) /* otherwise, skip one character */
1008 luaL_addchar(&b, *src++);
1009 else break; /* end of subject */
1010 if (anchor) break;
1012 if (!changed) /* no changes? */
1013 lua_pushvalue(L, 1); /* return original string */
1014 else { /* something changed */
1015 luaL_addlstring(&b, src, ms.src_end - src);
1016 luaL_pushresult(&b); /* create and return new string */
1018 lua_pushinteger(L, n); /* number of substitutions */
1019 return 2;
1022 /* }====================================================== */
1027 ** {======================================================
1028 ** STRING FORMAT
1029 ** =======================================================
1032 #if !defined(lua_number2strx) /* { */
1035 ** Hexadecimal floating-point formatter
1038 #define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
1042 ** Number of bits that goes into the first digit. It can be any value
1043 ** between 1 and 4; the following definition tries to align the number
1044 ** to nibble boundaries by making what is left after that first digit a
1045 ** multiple of 4.
1047 #define L_NBFD ((l_floatatt(MANT_DIG) - 1)%4 + 1)
1051 ** Add integer part of 'x' to buffer and return new 'x'
1053 static lua_Number adddigit(char *buff, int n, lua_Number x) {
1054 lua_Number dd = l_mathop(floor)(x); /* get integer part from 'x' */
1055 int d = (int)dd;
1056 buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */
1057 return x - dd; /* return what is left */
1061 static int num2straux(char *buff, int sz, lua_Number x) {
1062 /* if 'inf' or 'NaN', format it like '%g' */
1063 if (x != x || x == (lua_Number)HUGE_VAL || x == -(lua_Number)HUGE_VAL)
1064 return l_sprintf(buff, sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)x);
1065 else if (x == 0) { /* can be -0... */
1066 /* create "0" or "-0" followed by exponent */
1067 return l_sprintf(buff, sz, LUA_NUMBER_FMT "x0p+0", (LUAI_UACNUMBER)x);
1068 } else {
1069 int e;
1070 lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */
1071 int n = 0; /* character count */
1072 if (m < 0) { /* is number negative? */
1073 buff[n++] = '-'; /* add sign */
1074 m = -m; /* make it positive */
1076 buff[n++] = '0';
1077 buff[n++] = 'x'; /* add "0x" */
1078 m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
1079 e -= L_NBFD; /* this digit goes before the radix point */
1080 if (m > 0) { /* more digits? */
1081 buff[n++] = lua_getlocaledecpoint(); /* add radix point */
1082 do { /* add as many digits as needed */
1083 m = adddigit(buff, n++, m * 16);
1084 } while (m > 0);
1086 n += l_sprintf(buff + n, sz - n, "p%+d", e); /* add exponent */
1087 lua_assert(n < sz);
1088 return n;
1093 static int lua_number2strx(lua_State *L, char *buff, int sz,
1094 const char *fmt, lua_Number x) {
1095 int n = num2straux(buff, sz, x);
1096 if (fmt[SIZELENMOD] == 'A') {
1097 int i;
1098 for (i = 0; i < n; i++)
1099 buff[i] = toupper(uchar(buff[i]));
1100 } else if (l_unlikely(fmt[SIZELENMOD] != 'a'))
1101 return luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
1102 return n;
1105 #endif /* } */
1109 ** Maximum size for items formatted with '%f'. This size is produced
1110 ** by format('%.99f', -maxfloat), and is equal to 99 + 3 ('-', '.',
1111 ** and '\0') + number of decimal digits to represent maxfloat (which
1112 ** is maximum exponent + 1). (99+3+1, adding some extra, 110)
1114 #define MAX_ITEMF (110 + l_floatatt(MAX_10_EXP))
1118 ** All formats except '%f' do not need that large limit. The other
1119 ** float formats use exponents, so that they fit in the 99 limit for
1120 ** significant digits; 's' for large strings and 'q' add items directly
1121 ** to the buffer; all integer formats also fit in the 99 limit. The
1122 ** worst case are floats: they may need 99 significant digits, plus
1123 ** '0x', '-', '.', 'e+XXXX', and '\0'. Adding some extra, 120.
1125 #define MAX_ITEM 120
1128 /* valid flags in a format specification */
1129 #if !defined(L_FMTFLAGSF)
1131 /* valid flags for a, A, e, E, f, F, g, and G conversions */
1132 #define L_FMTFLAGSF "-+#0 "
1134 /* valid flags for o, x, and X conversions */
1135 #define L_FMTFLAGSX "-#0"
1137 /* valid flags for d and i conversions */
1138 #define L_FMTFLAGSI "-+0 "
1140 /* valid flags for u conversions */
1141 #define L_FMTFLAGSU "-0"
1143 /* valid flags for c, p, and s conversions */
1144 #define L_FMTFLAGSC "-"
1146 #endif
1150 ** Maximum size of each format specification (such as "%-099.99d"):
1151 ** Initial '%', flags (up to 5), width (2), period, precision (2),
1152 ** length modifier (8), conversion specifier, and final '\0', plus some
1153 ** extra.
1155 #define MAX_FORMAT 32
1158 static void addquoted(luaL_Buffer *b, const char *s, size_t len) {
1159 luaL_addchar(b, '"');
1160 while (len--) {
1161 if (*s == '"' || *s == '\\' || *s == '\n') {
1162 luaL_addchar(b, '\\');
1163 luaL_addchar(b, *s);
1164 } else if (iscntrl(uchar(*s))) {
1165 char buff[10];
1166 if (!isdigit(uchar(*(s + 1))))
1167 l_sprintf(buff, sizeof(buff), "\\%d", (int)uchar(*s));
1168 else
1169 l_sprintf(buff, sizeof(buff), "\\%03d", (int)uchar(*s));
1170 luaL_addstring(b, buff);
1171 } else
1172 luaL_addchar(b, *s);
1173 s++;
1175 luaL_addchar(b, '"');
1180 ** Serialize a floating-point number in such a way that it can be
1181 ** scanned back by Lua. Use hexadecimal format for "common" numbers
1182 ** (to preserve precision); inf, -inf, and NaN are handled separately.
1183 ** (NaN cannot be expressed as a numeral, so we write '(0/0)' for it.)
1185 static int quotefloat(lua_State *L, char *buff, lua_Number n) {
1186 const char *s; /* for the fixed representations */
1187 if (n == (lua_Number)HUGE_VAL) /* inf? */
1188 s = "1e9999";
1189 else if (n == -(lua_Number)HUGE_VAL) /* -inf? */
1190 s = "-1e9999";
1191 else if (n != n) /* NaN? */
1192 s = "(0/0)";
1193 else { /* format number as hexadecimal */
1194 int nb = lua_number2strx(L, buff, MAX_ITEM,
1195 "%" LUA_NUMBER_FRMLEN "a", n);
1196 /* ensures that 'buff' string uses a dot as the radix character */
1197 if (memchr(buff, '.', nb) == NULL) { /* no dot? */
1198 char point = lua_getlocaledecpoint(); /* try locale point */
1199 char *ppoint = (char *)memchr(buff, point, nb);
1200 if (ppoint) *ppoint = '.'; /* change it to a dot */
1202 return nb;
1204 /* for the fixed representations */
1205 return l_sprintf(buff, MAX_ITEM, "%s", s);
1209 static void addliteral(lua_State *L, luaL_Buffer *b, int arg) {
1210 switch (lua_type(L, arg)) {
1211 case LUA_TSTRING: {
1212 size_t len;
1213 const char *s = lua_tolstring(L, arg, &len);
1214 addquoted(b, s, len);
1215 break;
1217 case LUA_TNUMBER: {
1218 char *buff = luaL_prepbuffsize(b, MAX_ITEM);
1219 int nb;
1220 if (!lua_isinteger(L, arg)) /* float? */
1221 nb = quotefloat(L, buff, lua_tonumber(L, arg));
1222 else { /* integers */
1223 lua_Integer n = lua_tointeger(L, arg);
1224 const char *format = (n == LUA_MININTEGER) /* corner case? */
1225 ? "0x%" LUA_INTEGER_FRMLEN "x" /* use hex */
1226 : LUA_INTEGER_FMT; /* else use default format */
1227 nb = l_sprintf(buff, MAX_ITEM, format, (LUAI_UACINT)n);
1229 luaL_addsize(b, nb);
1230 break;
1232 case LUA_TNIL:
1233 case LUA_TBOOLEAN: {
1234 luaL_tolstring(L, arg, NULL);
1235 luaL_addvalue(b);
1236 break;
1238 default: {
1239 luaL_argerror(L, arg, "value has no literal form");
1245 static const char *get2digits(const char *s) {
1246 if (isdigit(uchar(*s))) {
1247 s++;
1248 if (isdigit(uchar(*s))) s++; /* (2 digits at most) */
1250 return s;
1255 ** Check whether a conversion specification is valid. When called,
1256 ** first character in 'form' must be '%' and last character must
1257 ** be a valid conversion specifier. 'flags' are the accepted flags;
1258 ** 'precision' signals whether to accept a precision.
1260 static void checkformat(lua_State *L, const char *form, const char *flags,
1261 int precision) {
1262 const char *spec = form + 1; /* skip '%' */
1263 spec += strspn(spec, flags); /* skip flags */
1264 if (*spec != '0') { /* a width cannot start with '0' */
1265 spec = get2digits(spec); /* skip width */
1266 if (*spec == '.' && precision) {
1267 spec++;
1268 spec = get2digits(spec); /* skip precision */
1271 if (!isalpha(uchar(*spec))) /* did not go to the end? */
1272 luaL_error(L, "invalid conversion specification: '%s'", form);
1277 ** Get a conversion specification and copy it to 'form'.
1278 ** Return the address of its last character.
1280 static const char *getformat(lua_State *L, const char *strfrmt,
1281 char *form) {
1282 /* spans flags, width, and precision ('0' is included as a flag) */
1283 size_t len = strspn(strfrmt, L_FMTFLAGSF "123456789.");
1284 len++; /* adds following character (should be the specifier) */
1285 /* still needs space for '%', '\0', plus a length modifier */
1286 if (len >= MAX_FORMAT - 10)
1287 luaL_error(L, "invalid format (too long)");
1288 *(form++) = '%';
1289 memcpy(form, strfrmt, len * sizeof(char));
1290 *(form + len) = '\0';
1291 return strfrmt + len - 1;
1296 ** add length modifier into formats
1298 static void addlenmod(char *form, const char *lenmod) {
1299 size_t l = strlen(form);
1300 size_t lm = strlen(lenmod);
1301 char spec = form[l - 1];
1302 strcpy(form + l - 1, lenmod);
1303 form[l + lm - 1] = spec;
1304 form[l + lm] = '\0';
1308 static int str_format(lua_State *L) {
1309 int top = lua_gettop(L);
1310 int arg = 1;
1311 size_t sfl;
1312 const char *strfrmt = luaL_checklstring(L, arg, &sfl);
1313 const char *strfrmt_end = strfrmt + sfl;
1314 const char *flags;
1315 luaL_Buffer b;
1316 luaL_buffinit(L, &b);
1317 while (strfrmt < strfrmt_end) {
1318 if (*strfrmt != L_ESC)
1319 luaL_addchar(&b, *strfrmt++);
1320 else if (*++strfrmt == L_ESC)
1321 luaL_addchar(&b, *strfrmt++); /* %% */
1322 else { /* format item */
1323 char form[MAX_FORMAT]; /* to store the format ('%...') */
1324 int maxitem = MAX_ITEM; /* maximum length for the result */
1325 char *buff = luaL_prepbuffsize(&b, maxitem); /* to put result */
1326 int nb = 0; /* number of bytes in result */
1327 if (++arg > top)
1328 return luaL_argerror(L, arg, "no value");
1329 strfrmt = getformat(L, strfrmt, form);
1330 switch (*strfrmt++) {
1331 case 'c': {
1332 checkformat(L, form, L_FMTFLAGSC, 0);
1333 nb = l_sprintf(buff, maxitem, form, (int)luaL_checkinteger(L, arg));
1334 break;
1336 case 'd':
1337 case 'i':
1338 flags = L_FMTFLAGSI;
1339 goto intcase;
1340 case 'u':
1341 flags = L_FMTFLAGSU;
1342 goto intcase;
1343 case 'o':
1344 case 'x':
1345 case 'X':
1346 flags = L_FMTFLAGSX;
1347 intcase: {
1348 lua_Integer n = luaL_checkinteger(L, arg);
1349 checkformat(L, form, flags, 1);
1350 addlenmod(form, LUA_INTEGER_FRMLEN);
1351 nb = l_sprintf(buff, maxitem, form, (LUAI_UACINT)n);
1352 break;
1354 case 'a':
1355 case 'A':
1356 checkformat(L, form, L_FMTFLAGSF, 1);
1357 addlenmod(form, LUA_NUMBER_FRMLEN);
1358 nb = lua_number2strx(L, buff, maxitem, form,
1359 luaL_checknumber(L, arg));
1360 break;
1361 case 'f':
1362 maxitem = MAX_ITEMF; /* extra space for '%f' */
1363 buff = luaL_prepbuffsize(&b, maxitem);
1364 /* FALLTHROUGH */
1365 case 'e':
1366 case 'E':
1367 case 'g':
1368 case 'G': {
1369 lua_Number n = luaL_checknumber(L, arg);
1370 checkformat(L, form, L_FMTFLAGSF, 1);
1371 addlenmod(form, LUA_NUMBER_FRMLEN);
1372 nb = l_sprintf(buff, maxitem, form, (LUAI_UACNUMBER)n);
1373 break;
1375 case 'p': {
1376 const void *p = lua_topointer(L, arg);
1377 checkformat(L, form, L_FMTFLAGSC, 0);
1378 if (p == NULL) { /* avoid calling 'printf' with argument NULL */
1379 p = "(null)"; /* result */
1380 form[strlen(form) - 1] = 's'; /* format it as a string */
1382 nb = l_sprintf(buff, maxitem, form, p);
1383 break;
1385 case 'q': {
1386 if (form[2] != '\0') /* modifiers? */
1387 return luaL_error(L, "specifier '%%q' cannot have modifiers");
1388 addliteral(L, &b, arg);
1389 break;
1391 case 's': {
1392 size_t l;
1393 const char *s = luaL_tolstring(L, arg, &l);
1394 if (form[2] == '\0') /* no modifiers? */
1395 luaL_addvalue(&b); /* keep entire string */
1396 else {
1397 luaL_argcheck(L, l == strlen(s), arg, "string contains zeros");
1398 checkformat(L, form, L_FMTFLAGSC, 1);
1399 if (strchr(form, '.') == NULL && l >= 100) {
1400 /* no precision and string is too long to be formatted */
1401 luaL_addvalue(&b); /* keep entire string */
1402 } else { /* format the string into 'buff' */
1403 nb = l_sprintf(buff, maxitem, form, s);
1404 lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
1407 break;
1409 default: { /* also treat cases 'pnLlh' */
1410 return luaL_error(L, "invalid conversion '%s' to 'format'", form);
1413 lua_assert(nb < maxitem);
1414 luaL_addsize(&b, nb);
1417 luaL_pushresult(&b);
1418 return 1;
1421 /* }====================================================== */
1425 ** {======================================================
1426 ** PACK/UNPACK
1427 ** =======================================================
1431 /* value used for padding */
1432 #if !defined(LUAL_PACKPADBYTE)
1433 #define LUAL_PACKPADBYTE 0x00
1434 #endif
1436 /* maximum size for the binary representation of an integer */
1437 #define MAXINTSIZE 16
1439 /* number of bits in a character */
1440 #define NB CHAR_BIT
1442 /* mask for one character (NB 1's) */
1443 #define MC ((1 << NB) - 1)
1445 /* size of a lua_Integer */
1446 #define SZINT ((int)sizeof(lua_Integer))
1449 /* dummy union to get native endianness */
1450 static const union {
1451 int dummy;
1452 char little; /* true iff machine is little endian */
1453 } nativeendian = {1};
1457 ** information to pack/unpack stuff
1459 typedef struct Header {
1460 lua_State *L;
1461 int islittle;
1462 int maxalign;
1463 } Header;
1467 ** options for pack/unpack
1469 typedef enum KOption {
1470 Kint, /* signed integers */
1471 Kuint, /* unsigned integers */
1472 Kfloat, /* single-precision floating-point numbers */
1473 Knumber, /* Lua "native" floating-point numbers */
1474 Kdouble, /* double-precision floating-point numbers */
1475 Kchar, /* fixed-length strings */
1476 Kstring, /* strings with prefixed length */
1477 Kzstr, /* zero-terminated strings */
1478 Kpadding, /* padding */
1479 Kpaddalign, /* padding for alignment */
1480 Knop /* no-op (configuration or spaces) */
1481 } KOption;
1485 ** Read an integer numeral from string 'fmt' or return 'df' if
1486 ** there is no numeral
1488 static int digit(int c) { return '0' <= c && c <= '9'; }
1490 static int getnum(const char **fmt, int df) {
1491 if (!digit(**fmt)) /* no number? */
1492 return df; /* return default value */
1493 else {
1494 int a = 0;
1495 do {
1496 a = a * 10 + (*((*fmt)++) - '0');
1497 } while (digit(**fmt) && a <= ((int)MAXSIZE - 9) / 10);
1498 return a;
1504 ** Read an integer numeral and raises an error if it is larger
1505 ** than the maximum size for integers.
1507 static int getnumlimit(Header *h, const char **fmt, int df) {
1508 int sz = getnum(fmt, df);
1509 if (l_unlikely(sz > MAXINTSIZE || sz <= 0))
1510 return luaL_error(h->L, "integral size (%d) out of limits [1,%d]",
1511 sz, MAXINTSIZE);
1512 return sz;
1517 ** Initialize Header
1519 static void initheader(lua_State *L, Header *h) {
1520 h->L = L;
1521 h->islittle = nativeendian.little;
1522 h->maxalign = 1;
1527 ** Read and classify next option. 'size' is filled with option's size.
1529 static KOption getoption(Header *h, const char **fmt, int *size) {
1530 /* dummy structure to get native alignment requirements */
1531 struct cD { char c; union { LUAI_MAXALIGN; } u; };
1532 int opt = *((*fmt)++);
1533 *size = 0; /* default */
1534 switch (opt) {
1535 case 'b':
1536 *size = sizeof(char);
1537 return Kint;
1538 case 'B':
1539 *size = sizeof(char);
1540 return Kuint;
1541 case 'h':
1542 *size = sizeof(short);
1543 return Kint;
1544 case 'H':
1545 *size = sizeof(short);
1546 return Kuint;
1547 case 'l':
1548 *size = sizeof(long);
1549 return Kint;
1550 case 'L':
1551 *size = sizeof(long);
1552 return Kuint;
1553 case 'j':
1554 *size = sizeof(lua_Integer);
1555 return Kint;
1556 case 'J':
1557 *size = sizeof(lua_Integer);
1558 return Kuint;
1559 case 'T':
1560 *size = sizeof(size_t);
1561 return Kuint;
1562 case 'f':
1563 *size = sizeof(float);
1564 return Kfloat;
1565 case 'n':
1566 *size = sizeof(lua_Number);
1567 return Knumber;
1568 case 'd':
1569 *size = sizeof(double);
1570 return Kdouble;
1571 case 'i':
1572 *size = getnumlimit(h, fmt, sizeof(int));
1573 return Kint;
1574 case 'I':
1575 *size = getnumlimit(h, fmt, sizeof(int));
1576 return Kuint;
1577 case 's':
1578 *size = getnumlimit(h, fmt, sizeof(size_t));
1579 return Kstring;
1580 case 'c':
1581 *size = getnum(fmt, -1);
1582 if (l_unlikely(*size == -1))
1583 luaL_error(h->L, "missing size for format option 'c'");
1584 return Kchar;
1585 case 'z':
1586 return Kzstr;
1587 case 'x':
1588 *size = 1;
1589 return Kpadding;
1590 case 'X':
1591 return Kpaddalign;
1592 case ' ':
1593 break;
1594 case '<':
1595 h->islittle = 1;
1596 break;
1597 case '>':
1598 h->islittle = 0;
1599 break;
1600 case '=':
1601 h->islittle = nativeendian.little;
1602 break;
1603 case '!': {
1604 const int maxalign = offsetof(struct cD, u);
1605 h->maxalign = getnumlimit(h, fmt, maxalign);
1606 break;
1608 default:
1609 luaL_error(h->L, "invalid format option '%c'", opt);
1611 return Knop;
1616 ** Read, classify, and fill other details about the next option.
1617 ** 'psize' is filled with option's size, 'notoalign' with its
1618 ** alignment requirements.
1619 ** Local variable 'size' gets the size to be aligned. (Kpadal option
1620 ** always gets its full alignment, other options are limited by
1621 ** the maximum alignment ('maxalign'). Kchar option needs no alignment
1622 ** despite its size.
1624 static KOption getdetails(Header *h, size_t totalsize,
1625 const char **fmt, int *psize, int *ntoalign) {
1626 KOption opt = getoption(h, fmt, psize);
1627 int align = *psize; /* usually, alignment follows size */
1628 if (opt == Kpaddalign) { /* 'X' gets alignment from following option */
1629 if (**fmt == '\0' || getoption(h, fmt, &align) == Kchar || align == 0)
1630 luaL_argerror(h->L, 1, "invalid next option for option 'X'");
1632 if (align <= 1 || opt == Kchar) /* need no alignment? */
1633 *ntoalign = 0;
1634 else {
1635 if (align > h->maxalign) /* enforce maximum alignment */
1636 align = h->maxalign;
1637 if (l_unlikely((align & (align - 1)) != 0)) /* not a power of 2? */
1638 luaL_argerror(h->L, 1, "format asks for alignment not power of 2");
1639 *ntoalign = (align - (int)(totalsize & (align - 1))) & (align - 1);
1641 return opt;
1646 ** Pack integer 'n' with 'size' bytes and 'islittle' endianness.
1647 ** The final 'if' handles the case when 'size' is larger than
1648 ** the size of a Lua integer, correcting the extra sign-extension
1649 ** bytes if necessary (by default they would be zeros).
1651 static void packint(luaL_Buffer *b, lua_Unsigned n,
1652 int islittle, int size, int neg) {
1653 char *buff = luaL_prepbuffsize(b, size);
1654 int i;
1655 buff[islittle ? 0 : size - 1] = (char)(n & MC); /* first byte */
1656 for (i = 1; i < size; i++) {
1657 n >>= NB;
1658 buff[islittle ? i : size - 1 - i] = (char)(n & MC);
1660 if (neg && size > SZINT) { /* negative number need sign extension? */
1661 for (i = SZINT; i < size; i++) /* correct extra bytes */
1662 buff[islittle ? i : size - 1 - i] = (char)MC;
1664 luaL_addsize(b, size); /* add result to buffer */
1669 ** Copy 'size' bytes from 'src' to 'dest', correcting endianness if
1670 ** given 'islittle' is different from native endianness.
1672 static void copywithendian(char *dest, const char *src,
1673 int size, int islittle) {
1674 if (islittle == nativeendian.little)
1675 memcpy(dest, src, size);
1676 else {
1677 dest += size - 1;
1678 while (size-- != 0)
1679 *(dest--) = *(src++);
1684 static int str_pack(lua_State *L) {
1685 luaL_Buffer b;
1686 Header h;
1687 const char *fmt = luaL_checkstring(L, 1); /* format string */
1688 int arg = 1; /* current argument to pack */
1689 size_t totalsize = 0; /* accumulate total size of result */
1690 initheader(L, &h);
1691 lua_pushnil(L); /* mark to separate arguments from string buffer */
1692 luaL_buffinit(L, &b);
1693 while (*fmt != '\0') {
1694 int size, ntoalign;
1695 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1696 totalsize += ntoalign + size;
1697 while (ntoalign-- > 0)
1698 luaL_addchar(&b, LUAL_PACKPADBYTE); /* fill alignment */
1699 arg++;
1700 switch (opt) {
1701 case Kint: { /* signed integers */
1702 lua_Integer n = luaL_checkinteger(L, arg);
1703 if (size < SZINT) { /* need overflow check? */
1704 lua_Integer lim = (lua_Integer)1 << ((size * NB) - 1);
1705 luaL_argcheck(L, -lim <= n && n < lim, arg, "integer overflow");
1707 packint(&b, (lua_Unsigned)n, h.islittle, size, (n < 0));
1708 break;
1710 case Kuint: { /* unsigned integers */
1711 lua_Integer n = luaL_checkinteger(L, arg);
1712 if (size < SZINT) /* need overflow check? */
1713 luaL_argcheck(L, (lua_Unsigned)n < ((lua_Unsigned)1 << (size * NB)),
1714 arg, "unsigned overflow");
1715 packint(&b, (lua_Unsigned)n, h.islittle, size, 0);
1716 break;
1718 case Kfloat: { /* C float */
1719 float f = (float)luaL_checknumber(L, arg); /* get argument */
1720 char *buff = luaL_prepbuffsize(&b, sizeof(f));
1721 /* move 'f' to final result, correcting endianness if needed */
1722 copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
1723 luaL_addsize(&b, size);
1724 break;
1726 case Knumber: { /* Lua float */
1727 lua_Number f = luaL_checknumber(L, arg); /* get argument */
1728 char *buff = luaL_prepbuffsize(&b, sizeof(f));
1729 /* move 'f' to final result, correcting endianness if needed */
1730 copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
1731 luaL_addsize(&b, size);
1732 break;
1734 case Kdouble: { /* C double */
1735 double f = (double)luaL_checknumber(L, arg); /* get argument */
1736 char *buff = luaL_prepbuffsize(&b, sizeof(f));
1737 /* move 'f' to final result, correcting endianness if needed */
1738 copywithendian(buff, (char *)&f, sizeof(f), h.islittle);
1739 luaL_addsize(&b, size);
1740 break;
1742 case Kchar: { /* fixed-size string */
1743 size_t len;
1744 const char *s = luaL_checklstring(L, arg, &len);
1745 luaL_argcheck(L, len <= (size_t)size, arg,
1746 "string longer than given size");
1747 luaL_addlstring(&b, s, len); /* add string */
1748 while (len++ < (size_t)size) /* pad extra space */
1749 luaL_addchar(&b, LUAL_PACKPADBYTE);
1750 break;
1752 case Kstring: { /* strings with length count */
1753 size_t len;
1754 const char *s = luaL_checklstring(L, arg, &len);
1755 luaL_argcheck(L, size >= (int)sizeof(size_t) ||
1756 len < ((size_t)1 << (size * NB)),
1757 arg, "string length does not fit in given size");
1758 packint(&b, (lua_Unsigned)len, h.islittle, size, 0); /* pack length */
1759 luaL_addlstring(&b, s, len);
1760 totalsize += len;
1761 break;
1763 case Kzstr: { /* zero-terminated string */
1764 size_t len;
1765 const char *s = luaL_checklstring(L, arg, &len);
1766 luaL_argcheck(L, strlen(s) == len, arg, "string contains zeros");
1767 luaL_addlstring(&b, s, len);
1768 luaL_addchar(&b, '\0'); /* add zero at the end */
1769 totalsize += len + 1;
1770 break;
1772 case Kpadding:
1773 luaL_addchar(&b, LUAL_PACKPADBYTE); /* FALLTHROUGH */
1774 case Kpaddalign:
1775 case Knop:
1776 arg--; /* undo increment */
1777 break;
1780 luaL_pushresult(&b);
1781 return 1;
1785 static int str_packsize(lua_State *L) {
1786 Header h;
1787 const char *fmt = luaL_checkstring(L, 1); /* format string */
1788 size_t totalsize = 0; /* accumulate total size of result */
1789 initheader(L, &h);
1790 while (*fmt != '\0') {
1791 int size, ntoalign;
1792 KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
1793 luaL_argcheck(L, opt != Kstring && opt != Kzstr, 1,
1794 "variable-length format");
1795 size += ntoalign; /* total space used by option */
1796 luaL_argcheck(L, totalsize <= MAXSIZE - size, 1,
1797 "format result too large");
1798 totalsize += size;
1800 lua_pushinteger(L, (lua_Integer)totalsize);
1801 return 1;
1806 ** Unpack an integer with 'size' bytes and 'islittle' endianness.
1807 ** If size is smaller than the size of a Lua integer and integer
1808 ** is signed, must do sign extension (propagating the sign to the
1809 ** higher bits); if size is larger than the size of a Lua integer,
1810 ** it must check the unread bytes to see whether they do not cause an
1811 ** overflow.
1813 static lua_Integer unpackint(lua_State *L, const char *str,
1814 int islittle, int size, int issigned) {
1815 lua_Unsigned res = 0;
1816 int i;
1817 int limit = (size <= SZINT) ? size : SZINT;
1818 for (i = limit - 1; i >= 0; i--) {
1819 res <<= NB;
1820 res |= (lua_Unsigned)(unsigned char)str[islittle ? i : size - 1 - i];
1822 if (size < SZINT) { /* real size smaller than lua_Integer? */
1823 if (issigned) { /* needs sign extension? */
1824 lua_Unsigned mask = (lua_Unsigned)1 << (size * NB - 1);
1825 res = ((res ^ mask) - mask); /* do sign extension */
1827 } else if (size > SZINT) { /* must check unread bytes */
1828 int mask = (!issigned || (lua_Integer)res >= 0) ? 0 : MC;
1829 for (i = limit; i < size; i++) {
1830 if (l_unlikely((unsigned char)str[islittle ? i : size - 1 - i] != mask))
1831 luaL_error(L, "%d-byte integer does not fit into Lua Integer", size);
1834 return (lua_Integer)res;
1838 static int str_unpack(lua_State *L) {
1839 Header h;
1840 const char *fmt = luaL_checkstring(L, 1);
1841 size_t ld;
1842 const char *data = luaL_checklstring(L, 2, &ld);
1843 size_t pos = posrelatI(luaL_optinteger(L, 3, 1), ld) - 1;
1844 int n = 0; /* number of results */
1845 luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
1846 initheader(L, &h);
1847 while (*fmt != '\0') {
1848 int size, ntoalign;
1849 KOption opt = getdetails(&h, pos, &fmt, &size, &ntoalign);
1850 luaL_argcheck(L, (size_t)ntoalign + size <= ld - pos, 2,
1851 "data string too short");
1852 pos += ntoalign; /* skip alignment */
1853 /* stack space for item + next position */
1854 luaL_checkstack(L, 2, "too many results");
1855 n++;
1856 switch (opt) {
1857 case Kint:
1858 case Kuint: {
1859 lua_Integer res = unpackint(L, data + pos, h.islittle, size,
1860 (opt == Kint));
1861 lua_pushinteger(L, res);
1862 break;
1864 case Kfloat: {
1865 float f;
1866 copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
1867 lua_pushnumber(L, (lua_Number)f);
1868 break;
1870 case Knumber: {
1871 lua_Number f;
1872 copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
1873 lua_pushnumber(L, f);
1874 break;
1876 case Kdouble: {
1877 double f;
1878 copywithendian((char *)&f, data + pos, sizeof(f), h.islittle);
1879 lua_pushnumber(L, (lua_Number)f);
1880 break;
1882 case Kchar: {
1883 lua_pushlstring(L, data + pos, size);
1884 break;
1886 case Kstring: {
1887 size_t len = (size_t)unpackint(L, data + pos, h.islittle, size, 0);
1888 luaL_argcheck(L, len <= ld - pos - size, 2, "data string too short");
1889 lua_pushlstring(L, data + pos + size, len);
1890 pos += len; /* skip string */
1891 break;
1893 case Kzstr: {
1894 size_t len = strlen(data + pos);
1895 luaL_argcheck(L, pos + len < ld, 2,
1896 "unfinished string for format 'z'");
1897 lua_pushlstring(L, data + pos, len);
1898 pos += len + 1; /* skip string plus final '\0' */
1899 break;
1901 case Kpaddalign:
1902 case Kpadding:
1903 case Knop:
1904 n--; /* undo increment */
1905 break;
1907 pos += size;
1909 lua_pushinteger(L, pos + 1); /* next position */
1910 return n + 1;
1913 /* }====================================================== */
1916 static const luaL_Reg strlib[] = {
1917 {"byte", str_byte},
1918 {"char", str_char},
1919 {"dump", str_dump},
1920 {"find", str_find},
1921 {"format", str_format},
1922 {"gmatch", gmatch},
1923 {"gsub", str_gsub},
1924 {"len", str_len},
1925 {"lower", str_lower},
1926 {"match", str_match},
1927 {"rep", str_rep},
1928 {"reverse", str_reverse},
1929 {"sub", str_sub},
1930 {"upper", str_upper},
1931 {"pack", str_pack},
1932 {"packsize", str_packsize},
1933 {"unpack", str_unpack},
1934 {NULL, NULL}
1938 static void createmetatable(lua_State *L) {
1939 /* table to be metatable for strings */
1940 luaL_newlibtable(L, stringmetamethods);
1941 luaL_setfuncs(L, stringmetamethods, 0);
1942 lua_pushliteral(L, ""); /* dummy string */
1943 lua_pushvalue(L, -2); /* copy table */
1944 lua_setmetatable(L, -2); /* set table as metatable for strings */
1945 lua_pop(L, 1); /* pop dummy string */
1946 lua_pushvalue(L, -2); /* get string library */
1947 lua_setfield(L, -2, "__index"); /* metatable.__index = string */
1948 lua_pop(L, 1); /* pop metatable */
1953 ** Open string library
1955 LUAMOD_API int luaopen_string(lua_State *L) {
1956 luaL_newlib(L, strlib);
1957 createmetatable(L);
1958 return 1;