3 ** Standard library for string operations and pattern-matching
4 ** See Copyright Notice in lua.h
30 ** maximum number of captures that a pattern can do during
31 ** pattern-matching. This limit is arbitrary, but must fit in
34 #if !defined(LUA_MAXCAPTURES)
35 #define LUA_MAXCAPTURES 32
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))
50 (sizeof(size_t) < sizeof(int) ? MAX_SIZET : (size_t)(INT_MAX))
55 static int str_len(lua_State
*L
) {
57 luaL_checklstring(L
, 1, &l
);
58 lua_pushinteger(L
, (lua_Integer
)l
);
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
71 static size_t posrelatI(lua_Integer pos
, size_t len
) {
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
,
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;
100 static int str_sub(lua_State
*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
);
106 lua_pushlstring(L
, s
+ start
- 1, (end
- start
) + 1);
107 else lua_pushliteral(L
, "");
112 static int str_reverse(lua_State
*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
);
124 static int str_lower(lua_State
*L
) {
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
);
137 static int str_upper(lua_State
*L
) {
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
);
150 static int str_rep(lua_State
*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
);
163 while (n
-- > 1) { /* first n-1 copies (followed by separator) */
164 memcpy(p
, s
, l
* sizeof(char));
166 if (lsep
> 0) { /* empty 'memcpy' is not that cheap */
167 memcpy(p
, sep
, lsep
* sizeof(char));
171 memcpy(p
, s
, l
* sizeof(char)); /* last copy (not followed by separator) */
172 luaL_pushresultsize(&b
, totallen
);
178 static int str_byte(lua_State
*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
);
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]));
196 static int str_char(lua_State
*L
) {
197 int n
= lua_gettop(L
); /* number of arguments */
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");
206 luaL_pushresultsize(&b
, n
);
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
218 int init
; /* true iff buffer has been initialized */
223 static int writer(lua_State
*L
, const void *b
, size_t size
, void *ud
) {
224 struct str_Writer
*state
= (struct str_Writer
*)ud
;
227 luaL_buffinit(L
, &state
->B
);
229 luaL_addlstring(&state
->B
, (const char *)b
, size
);
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 */
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
);
249 ** {======================================================
251 ** =======================================================
254 #if defined(LUA_NOCVTS2N) /* { */
256 /* no coercion from strings to numbers */
258 static const luaL_Reg stringmetamethods
[] = {
259 {"__index", NULL
}, /* placeholder */
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
);
269 } else { /* check whether it is a numerical string */
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 */
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 */
345 /* }====================================================== */
348 ** {======================================================
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 */
363 int matchdepth
; /* control for recursive depth (to avoid C stack overflow) */
364 unsigned char level
; /* total number of captures (finished or unfinished) */
368 } capture
[LUA_MAXCAPTURES
];
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
383 #define SPECIALS "^$*+?.([%-"
386 static 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);
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
) {
406 if (l_unlikely(p
== ms
->p_end
))
407 luaL_error(ms
->L
, "malformed pattern (ends with '%%')");
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. '%]') */
427 static int match_class(int c
, int cl
) {
429 switch (tolower(cl
)) {
462 break; /* deprecated option */
466 return (islower(cl
) ? res
: !res
);
470 static int matchbracketclass(int c
, const char *p
, const char *ec
) {
472 if (*(p
+ 1) == '^') {
474 p
++; /* skip the '^' */
479 if (match_class(c
, uchar(*p
)))
481 } else if ((*(p
+ 1) == '-') && (p
+ 2 < ec
)) {
483 if (uchar(*(p
- 2)) <= c
&& c
<= uchar(*p
))
485 } else if (uchar(*p
) == c
) return sig
;
491 static int singlematch(MatchState
*ms
, const char *s
, const char *p
,
493 if (s
>= ms
->src_end
)
499 return 1; /* matches any char */
501 return match_class(c
, uchar(*(p
+ 1)));
503 return matchbracketclass(c
, p
, ep
- 1);
505 return (uchar(*p
) == c
);
511 static const char *matchbalance(MatchState
*ms
, const char *s
,
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
;
520 while (++s
< ms
->src_end
) {
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
))
535 /* keeps trying to match with the maximum repetitions */
537 const char *res
= match(ms
, (s
+ i
), ep
+ 1);
539 i
--; /* else didn't match; reduce 1 repetition to try again */
545 static const char *min_expand(MatchState
*ms
, const char *s
,
546 const char *p
, const char *ep
) {
548 const char *res
= match(ms
, s
, ep
+ 1);
551 else if (singlematch(ms
, s
, p
, ep
))
552 s
++; /* try with one more repetition */
558 static const char *start_capture(MatchState
*ms
, const char *s
,
559 const char *p
, int what
) {
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 */
572 static const char *end_capture(MatchState
*ms
, const char *s
,
574 int l
= capture_to_close(ms
);
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 */
583 static const char *match_capture(MatchState
*ms
, const char *s
, int l
) {
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)
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? */
600 case '(': { /* start capture */
601 if (*(p
+ 1) == ')') /* position capture? */
602 s
= start_capture(ms
, s
, p
+ 2, CAP_POSITION
);
604 s
= start_capture(ms
, s
, p
+ 1, CAP_UNFINISHED
);
607 case ')': { /* end capture */
608 s
= end_capture(ms
, s
, p
+ 1);
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 */
617 case L_ESC
: { /* escaped sequences not in the format class[*+?-]? */
619 case 'b': { /* balanced string? */
620 s
= matchbalance(ms
, s
, p
+ 2);
623 goto init
; /* return match(ms, s, p + 4); */
624 } /* else fail (s == NULL) */
627 case 'f': { /* frontier? */
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)) {
638 goto init
; /* return match(ms, s, ep); */
640 s
= NULL
; /* match failed */
652 case '9': { /* capture results (%0-%9)? */
653 s
= match_capture(ms
, s
, uchar(*(p
+ 1)));
656 goto init
; /* return match(ms, s, p + 2) */
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? */
672 goto init
; /* return match(ms, s, ep + 1); */
673 } else /* '+' or no suffix */
675 } else { /* matched once */
676 switch (*ep
) { /* handle optional suffix */
677 case '?': { /* optional */
679 if ((res
= match(ms
, s
+ 1, ep
+ 1)) != NULL
)
683 goto init
; /* else return match(ms, s, ep + 1); */
687 case '+': /* 1 or more repetitions */
688 s
++; /* 1 match already done */
690 case '*': /* 0 or more repetitions */
691 s
= max_expand(ms
, s
, p
, ep
);
693 case '-': /* 0 or more repetitions (minimum) */
694 s
= min_expand(ms
, s
, p
, ep
);
696 default: /* no suffix */
699 goto init
; /* return match(ms, s + 1, ep); */
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' */
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)
724 else { /* correct 'l1' and 's1' to try again */
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);
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);
761 ** Push the i-th capture on the stack.
763 static void push_onecapture(MatchState
*ms
, int i
, const char *s
,
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
) {
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
) {
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 */
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
) {
798 ms
->matchdepth
= MAXCCALLS
;
800 ms
->src_end
= s
+ ls
;
805 static void reprepstate(MatchState
*ms
) {
807 lua_assert(ms
->matchdepth
== MAXCCALLS
);
811 static int str_find_aux(lua_State
*L
, int find
) {
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 */
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
);
825 lua_pushinteger(L
, (s2
- s
) + 1);
826 lua_pushinteger(L
, (s2
- s
) + lp
);
831 const char *s1
= s
+ init
;
832 int anchor
= (*p
== '^');
835 lp
--; /* skip anchor character */
837 prepstate(&ms
, L
, s
, ls
, p
, lp
);
841 if ((res
= match(&ms
, s1
, p
)) != NULL
) {
843 lua_pushinteger(L
, (s1
- s
) + 1); /* start */
844 lua_pushinteger(L
, res
- s
); /* end */
845 return push_captures(&ms
, NULL
, 0) + 2;
847 return push_captures(&ms
, s1
, res
);
849 } while (s1
++ < ms
.src_end
&& !anchor
);
851 luaL_pushfail(L
); /* not found */
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 */
875 static int gmatch_aux(lua_State
*L
) {
876 GMatchState
*gm
= (GMatchState
*)lua_touserdata(L
, lua_upvalueindex(3));
879 for (src
= gm
->src
; src
<= gm
->ms
.src_end
; src
++) {
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
) {
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;
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
);
904 gm
->lastmatch
= NULL
;
905 lua_pushcclosure(L
, gmatch_aux
, 3);
910 static void add_s(MatchState
*ms
, luaL_Buffer
*b
, const char *s
,
913 lua_State
*L
= ms
->L
;
914 const char *news
= lua_tolstring(L
, 3, &l
);
916 while ((p
= (char *)memchr(news
, L_ESC
, l
)) != NULL
) {
917 luaL_addlstring(b
, news
, p
- news
);
919 if (*p
== L_ESC
) /* '%%' */
921 else if (*p
== '0') /* '%0' */
922 luaL_addlstring(b
, s
, e
- s
);
923 else if (isdigit(uchar(*p
))) { /* '%n' */
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 */
929 luaL_addlstring(b
, cap
, resl
);
931 luaL_error(L
, "invalid use of '%c' in replacement string", L_ESC
);
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
;
948 case LUA_TFUNCTION
: { /* call the function */
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 */
955 case LUA_TTABLE
: { /* index the table */
956 push_onecapture(ms
, 0, s
, e
); /* first capture is the index */
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));
973 luaL_addvalue(b
); /* add result to accumulator */
974 return 1; /* something changed */
979 static int str_gsub(lua_State
*L
) {
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 */
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
);
997 lp
--; /* skip anchor character */
999 prepstate(&ms
, L
, src
, srcl
, p
, lp
);
1002 reprepstate(&ms
); /* (re)prepare state for new match */
1003 if ((e
= match(&ms
, src
, p
)) != NULL
&& e
!= lastmatch
) { /* match? */
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 */
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 */
1022 /* }====================================================== */
1027 ** {======================================================
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
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' */
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
);
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 */
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);
1086 n
+= l_sprintf(buff
+ n
, sz
- n
, "p%+d", e
); /* add exponent */
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') {
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");
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 "-"
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
1155 #define MAX_FORMAT 32
1158 static void addquoted(luaL_Buffer
*b
, const char *s
, size_t len
) {
1159 luaL_addchar(b
, '"');
1161 if (*s
== '"' || *s
== '\\' || *s
== '\n') {
1162 luaL_addchar(b
, '\\');
1163 luaL_addchar(b
, *s
);
1164 } else if (iscntrl(uchar(*s
))) {
1166 if (!isdigit(uchar(*(s
+ 1))))
1167 l_sprintf(buff
, sizeof(buff
), "\\%d", (int)uchar(*s
));
1169 l_sprintf(buff
, sizeof(buff
), "\\%03d", (int)uchar(*s
));
1170 luaL_addstring(b
, buff
);
1172 luaL_addchar(b
, *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? */
1189 else if (n
== -(lua_Number
)HUGE_VAL
) /* -inf? */
1191 else if (n
!= n
) /* NaN? */
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 */
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
)) {
1213 const char *s
= lua_tolstring(L
, arg
, &len
);
1214 addquoted(b
, s
, len
);
1218 char *buff
= luaL_prepbuffsize(b
, MAX_ITEM
);
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
);
1233 case LUA_TBOOLEAN
: {
1234 luaL_tolstring(L
, arg
, NULL
);
1239 luaL_argerror(L
, arg
, "value has no literal form");
1245 static const char *get2digits(const char *s
) {
1246 if (isdigit(uchar(*s
))) {
1248 if (isdigit(uchar(*s
))) s
++; /* (2 digits at most) */
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
,
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
) {
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
,
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)");
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
);
1312 const char *strfrmt
= luaL_checklstring(L
, arg
, &sfl
);
1313 const char *strfrmt_end
= strfrmt
+ sfl
;
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 */
1328 return luaL_argerror(L
, arg
, "no value");
1329 strfrmt
= getformat(L
, strfrmt
, form
);
1330 switch (*strfrmt
++) {
1332 checkformat(L
, form
, L_FMTFLAGSC
, 0);
1333 nb
= l_sprintf(buff
, maxitem
, form
, (int)luaL_checkinteger(L
, arg
));
1338 flags
= L_FMTFLAGSI
;
1341 flags
= L_FMTFLAGSU
;
1346 flags
= L_FMTFLAGSX
;
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
);
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
));
1362 maxitem
= MAX_ITEMF
; /* extra space for '%f' */
1363 buff
= luaL_prepbuffsize(&b
, maxitem
);
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
);
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
);
1386 if (form
[2] != '\0') /* modifiers? */
1387 return luaL_error(L
, "specifier '%%q' cannot have modifiers");
1388 addliteral(L
, &b
, arg
);
1393 const char *s
= luaL_tolstring(L
, arg
, &l
);
1394 if (form
[2] == '\0') /* no modifiers? */
1395 luaL_addvalue(&b
); /* keep entire string */
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' */
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
);
1421 /* }====================================================== */
1425 ** {======================================================
1427 ** =======================================================
1431 /* value used for padding */
1432 #if !defined(LUAL_PACKPADBYTE)
1433 #define LUAL_PACKPADBYTE 0x00
1436 /* maximum size for the binary representation of an integer */
1437 #define MAXINTSIZE 16
1439 /* number of bits in a character */
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 {
1452 char little
; /* true iff machine is little endian */
1453 } nativeendian
= {1};
1457 ** information to pack/unpack stuff
1459 typedef struct 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) */
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 */
1496 a
= a
* 10 + (*((*fmt
)++) - '0');
1497 } while (digit(**fmt
) && a
<= ((int)MAXSIZE
- 9) / 10);
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]",
1517 ** Initialize Header
1519 static void initheader(lua_State
*L
, Header
*h
) {
1521 h
->islittle
= nativeendian
.little
;
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 */
1536 *size
= sizeof(char);
1539 *size
= sizeof(char);
1542 *size
= sizeof(short);
1545 *size
= sizeof(short);
1548 *size
= sizeof(long);
1551 *size
= sizeof(long);
1554 *size
= sizeof(lua_Integer
);
1557 *size
= sizeof(lua_Integer
);
1560 *size
= sizeof(size_t);
1563 *size
= sizeof(float);
1566 *size
= sizeof(lua_Number
);
1569 *size
= sizeof(double);
1572 *size
= getnumlimit(h
, fmt
, sizeof(int));
1575 *size
= getnumlimit(h
, fmt
, sizeof(int));
1578 *size
= getnumlimit(h
, fmt
, sizeof(size_t));
1581 *size
= getnum(fmt
, -1);
1582 if (l_unlikely(*size
== -1))
1583 luaL_error(h
->L
, "missing size for format option 'c'");
1601 h
->islittle
= nativeendian
.little
;
1604 const int maxalign
= offsetof(struct cD
, u
);
1605 h
->maxalign
= getnumlimit(h
, fmt
, maxalign
);
1609 luaL_error(h
->L
, "invalid format option '%c'", opt
);
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? */
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);
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
);
1655 buff
[islittle
? 0 : size
- 1] = (char)(n
& MC
); /* first byte */
1656 for (i
= 1; i
< size
; i
++) {
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
);
1679 *(dest
--) = *(src
++);
1684 static int str_pack(lua_State
*L
) {
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 */
1691 lua_pushnil(L
); /* mark to separate arguments from string buffer */
1692 luaL_buffinit(L
, &b
);
1693 while (*fmt
!= '\0') {
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 */
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));
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);
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
);
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
);
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
);
1742 case Kchar
: { /* fixed-size string */
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
);
1752 case Kstring
: { /* strings with length count */
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
);
1763 case Kzstr
: { /* zero-terminated string */
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;
1773 luaL_addchar(&b
, LUAL_PACKPADBYTE
); /* FALLTHROUGH */
1776 arg
--; /* undo increment */
1780 luaL_pushresult(&b
);
1785 static int str_packsize(lua_State
*L
) {
1787 const char *fmt
= luaL_checkstring(L
, 1); /* format string */
1788 size_t totalsize
= 0; /* accumulate total size of result */
1790 while (*fmt
!= '\0') {
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");
1800 lua_pushinteger(L
, (lua_Integer
)totalsize
);
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
1813 static lua_Integer
unpackint(lua_State
*L
, const char *str
,
1814 int islittle
, int size
, int issigned
) {
1815 lua_Unsigned res
= 0;
1817 int limit
= (size
<= SZINT
) ? size
: SZINT
;
1818 for (i
= limit
- 1; i
>= 0; i
--) {
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
) {
1840 const char *fmt
= luaL_checkstring(L
, 1);
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");
1847 while (*fmt
!= '\0') {
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");
1859 lua_Integer res
= unpackint(L
, data
+ pos
, h
.islittle
, size
,
1861 lua_pushinteger(L
, res
);
1866 copywithendian((char *)&f
, data
+ pos
, sizeof(f
), h
.islittle
);
1867 lua_pushnumber(L
, (lua_Number
)f
);
1872 copywithendian((char *)&f
, data
+ pos
, sizeof(f
), h
.islittle
);
1873 lua_pushnumber(L
, f
);
1878 copywithendian((char *)&f
, data
+ pos
, sizeof(f
), h
.islittle
);
1879 lua_pushnumber(L
, (lua_Number
)f
);
1883 lua_pushlstring(L
, data
+ pos
, size
);
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 */
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' */
1904 n
--; /* undo increment */
1909 lua_pushinteger(L
, pos
+ 1); /* next position */
1913 /* }====================================================== */
1916 static const luaL_Reg strlib
[] = {
1921 {"format", str_format
},
1925 {"lower", str_lower
},
1926 {"match", str_match
},
1928 {"reverse", str_reverse
},
1930 {"upper", str_upper
},
1932 {"packsize", str_packsize
},
1933 {"unpack", str_unpack
},
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
);