Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
lstrlib.c File Reference
#include <ctype.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

Go to the source code of this file.

Data Structures

struct  MatchState
 

Macros

#define lstrlib_c
 
#define LUA_LIB
 
#define uchar(c)   ((unsigned char)(c))
 
#define CAP_UNFINISHED   (-1)
 
#define CAP_POSITION   (-2)
 
#define L_ESC   '%'
 
#define SPECIALS   "^$*+?.([%-"
 
#define MAX_ITEM   512
 
#define FLAGS   "-+ #0"
 
#define MAX_FORMAT   (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
 

Typedefs

typedef struct MatchState MatchState
 

Functions

static int str_len (lua_State *L)
 
static ptrdiff_t posrelat (ptrdiff_t pos, size_t len)
 
static int str_sub (lua_State *L)
 
static int str_reverse (lua_State *L)
 
static int str_lower (lua_State *L)
 
static int str_upper (lua_State *L)
 
static int str_rep (lua_State *L)
 
static int str_byte (lua_State *L)
 
static int str_char (lua_State *L)
 
static int writer (lua_State *L, const void *b, size_t size, void *B)
 
static int str_dump (lua_State *L)
 
static int check_capture (MatchState *ms, int l)
 
static int capture_to_close (MatchState *ms)
 
static const char * classend (MatchState *ms, const char *p)
 
static int match_class (int c, int cl)
 
static int matchbracketclass (int c, const char *p, const char *ec)
 
static int singlematch (int c, const char *p, const char *ep)
 
static const char * match (MatchState *ms, const char *s, const char *p)
 
static const char * matchbalance (MatchState *ms, const char *s, const char *p)
 
static const char * max_expand (MatchState *ms, const char *s, const char *p, const char *ep)
 
static const char * min_expand (MatchState *ms, const char *s, const char *p, const char *ep)
 
static const char * start_capture (MatchState *ms, const char *s, const char *p, int what)
 
static const char * end_capture (MatchState *ms, const char *s, const char *p)
 
static const char * match_capture (MatchState *ms, const char *s, int l)
 
static const char * lmemfind (const char *s1, size_t l1, const char *s2, size_t l2)
 
static void push_onecapture (MatchState *ms, int i, const char *s, const char *e)
 
static int push_captures (MatchState *ms, const char *s, const char *e)
 
static int str_find_aux (lua_State *L, int find)
 
static int str_find (lua_State *L)
 
static int str_match (lua_State *L)
 
static int gmatch_aux (lua_State *L)
 
static int gmatch (lua_State *L)
 
static int gfind_nodef (lua_State *L)
 
static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, const char *e)
 
static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, const char *e)
 
static int str_gsub (lua_State *L)
 
static void addquoted (lua_State *L, luaL_Buffer *b, int arg)
 
static const char * scanformat (lua_State *L, const char *strfrmt, char *form)
 
static void addintlen (char *form)
 
static int str_format (lua_State *L)
 
static void createmetatable (lua_State *L)
 
LUALIB_API int luaopen_string (lua_State *L)
 

Variables

static const luaL_Reg strlib []
 

Macro Definition Documentation

◆ CAP_POSITION

#define CAP_POSITION   (-2)

Definition at line 168 of file lua-5.1.5/src/lstrlib.c.

Referenced by match(), and push_onecapture().

◆ CAP_UNFINISHED

#define CAP_UNFINISHED   (-1)

◆ FLAGS

#define FLAGS   "-+ #0"

Definition at line 688 of file lua-5.1.5/src/lstrlib.c.

Referenced by scanformat().

◆ L_ESC

#define L_ESC   '%'

◆ lstrlib_c

#define lstrlib_c

Definition at line 14 of file lua-5.1.5/src/lstrlib.c.

◆ LUA_LIB

#define LUA_LIB

Definition at line 15 of file lua-5.1.5/src/lstrlib.c.

◆ MAX_FORMAT

#define MAX_FORMAT   (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)

Definition at line 693 of file lua-5.1.5/src/lstrlib.c.

Referenced by str_format().

◆ MAX_ITEM

#define MAX_ITEM   512

Definition at line 686 of file lua-5.1.5/src/lstrlib.c.

Referenced by str_format().

◆ SPECIALS

#define SPECIALS   "^$*+?.([%-"

Definition at line 183 of file lua-5.1.5/src/lstrlib.c.

Referenced by str_find_aux().

◆ uchar

#define uchar ( c)    ((unsigned char)(c))

Typedef Documentation

◆ MatchState

typedef struct MatchState MatchState

Function Documentation

◆ add_s()

static void add_s ( MatchState * ms,
luaL_Buffer * b,
const char * s,
const char * e )
static

Definition at line 590 of file lua-5.1.5/src/lstrlib.c.

591 {
592 size_t l, i;
593 const char *news = lua_tolstring(ms->L, 3, &l);
594 for (i = 0; i < l; i++) {
595 if (news[i] != L_ESC)
596 luaL_addchar(b, news[i]);
597 else {
598 i++; /* skip ESC */
599 if (!isdigit(uchar(news[i])))
600 luaL_addchar(b, news[i]);
601 else if (news[i] == '0')
602 luaL_addlstring(b, s, e - s);
603 else {
604 push_onecapture(ms, news[i] - '1', s, e);
605 luaL_addvalue(b); /* add capture to accumulated result */
606 }
607 }
608 }
609}
LUA_API const char * lua_tolstring(lua_State *L, int idx, size_t *len)
LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l)
LUALIB_API void luaL_addvalue(luaL_Buffer *B)
#define luaL_addchar(B, c)
static void push_onecapture(MatchState *ms, int i, const char *s, const char *e)
#define L_ESC
#define uchar(c)
CURL_EXTERN CURLMcode curl_socket_t s
Definition multi.h:318

References MatchState::L, L_ESC, lua_tolstring(), luaL_addchar, luaL_addlstring(), luaL_addvalue(), push_onecapture(), s, and uchar.

Referenced by add_value().

◆ add_value()

static void add_value ( MatchState * ms,
luaL_Buffer * b,
const char * s,
const char * e )
static

Definition at line 612 of file lua-5.1.5/src/lstrlib.c.

613 {
614 lua_State *L = ms->L;
615 switch (lua_type(L, 3)) {
616 case LUA_TNUMBER:
617 case LUA_TSTRING: {
618 add_s(ms, b, s, e);
619 return;
620 }
621 case LUA_TFUNCTION: {
622 int n;
623 lua_pushvalue(L, 3);
624 n = push_captures(ms, s, e);
625 lua_call(L, n, 1);
626 break;
627 }
628 case LUA_TTABLE: {
629 push_onecapture(ms, 0, s, e);
630 lua_gettable(L, 3);
631 break;
632 }
633 }
634 if (!lua_toboolean(L, -1)) { /* nil or false? */
635 lua_pop(L, 1);
636 lua_pushlstring(L, s, e - s); /* keep original text */
637 }
638 else if (!lua_isstring(L, -1))
639 luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
640 luaL_addvalue(b); /* add result to accumulator */
641}
LUA_API int lua_toboolean(lua_State *L, int idx)
LUA_API void lua_pushvalue(lua_State *L, int idx)
LUA_API int lua_type(lua_State *L, int idx)
LUA_API void lua_gettable(lua_State *L, int idx)
LUA_API int lua_isstring(lua_State *L, int idx)
LUA_API void lua_pushlstring(lua_State *L, const char *s, size_t len)
LUALIB_API int luaL_error(lua_State *L, const char *fmt,...)
#define luaL_typename(L, i)
static int push_captures(MatchState *ms, const char *s, const char *e)
static void add_s(MatchState *ms, luaL_Buffer *b, const char *s, const char *e)
#define LUA_TTABLE
#define LUA_TSTRING
#define LUA_TNUMBER
#define lua_pop(L, n)
#define LUA_TFUNCTION
#define lua_call(L, n, r)

References add_s(), MatchState::L, lua_call, lua_gettable(), lua_isstring(), lua_pop, lua_pushlstring(), lua_pushvalue(), LUA_TFUNCTION, LUA_TNUMBER, lua_toboolean(), LUA_TSTRING, LUA_TTABLE, lua_type(), luaL_addvalue(), luaL_error(), luaL_typename, push_captures(), push_onecapture(), and s.

Referenced by str_gsub().

◆ addintlen()

static void addintlen ( char * form)
static

Definition at line 747 of file lua-5.1.5/src/lstrlib.c.

747 {
748 size_t l = strlen(form);
749 char spec = form[l - 1];
750 strcpy(form + l - 1, LUA_INTFRMLEN);
751 form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
752 form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
753}
#define LUA_INTFRMLEN

References LUA_INTFRMLEN.

Referenced by str_format().

◆ addquoted()

static void addquoted ( lua_State * L,
luaL_Buffer * b,
int arg )
static

Definition at line 696 of file lua-5.1.5/src/lstrlib.c.

696 {
697 size_t l;
698 const char *s = luaL_checklstring(L, arg, &l);
699 luaL_addchar(b, '"');
700 while (l--) {
701 switch (*s) {
702 case '"': case '\\': case '\n': {
703 luaL_addchar(b, '\\');
704 luaL_addchar(b, *s);
705 break;
706 }
707 case '\r': {
708 luaL_addlstring(b, "\\r", 2);
709 break;
710 }
711 case '\0': {
712 luaL_addlstring(b, "\\000", 4);
713 break;
714 }
715 default: {
716 luaL_addchar(b, *s);
717 break;
718 }
719 }
720 s++;
721 }
722 luaL_addchar(b, '"');
723}
CURL_EXTERN int void * arg
Definition curl.h:2622
LUALIB_API const char * luaL_checklstring(lua_State *L, int narg, size_t *len)

References arg, luaL_addchar, luaL_addlstring(), luaL_checklstring(), and s.

Referenced by str_format().

◆ capture_to_close()

static int capture_to_close ( MatchState * ms)
static

Definition at line 194 of file lua-5.1.5/src/lstrlib.c.

194 {
195 int level = ms->level;
196 for (level--; level>=0; level--)
197 if (ms->capture[level].len == CAP_UNFINISHED) return level;
198 return luaL_error(ms->L, "invalid pattern capture");
199}
#define CAP_UNFINISHED
struct MatchState::@54 capture[LUA_MAXCAPTURES]

References CAP_UNFINISHED, MatchState::capture, MatchState::L, MatchState::len, MatchState::level, and luaL_error().

Referenced by end_capture().

◆ check_capture()

static int check_capture ( MatchState * ms,
int l )
static

Definition at line 186 of file lua-5.1.5/src/lstrlib.c.

186 {
187 l -= '1';
188 if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED)
189 return luaL_error(ms->L, "invalid capture index");
190 return l;
191}

References CAP_UNFINISHED, MatchState::capture, MatchState::L, MatchState::len, MatchState::level, and luaL_error().

Referenced by match_capture().

◆ classend()

static const char * classend ( MatchState * ms,
const char * p )
static

Definition at line 202 of file lua-5.1.5/src/lstrlib.c.

202 {
203 switch (*p++) {
204 case L_ESC: {
205 if (*p == '\0')
206 luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
207 return p+1;
208 }
209 case '[': {
210 if (*p == '^') p++;
211 do { /* look for a `]' */
212 if (*p == '\0')
213 luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
214 if (*(p++) == L_ESC && *p != '\0')
215 p++; /* skip escapes (e.g. `%]') */
216 } while (*p != ']');
217 return p+1;
218 }
219 default: {
220 return p;
221 }
222 }
223}
#define LUA_QL(x)

References MatchState::L, L_ESC, LUA_QL, and luaL_error().

Referenced by match().

◆ createmetatable()

static void createmetatable ( lua_State * L)
static

Definition at line 847 of file lua-5.1.5/src/lstrlib.c.

847 {
848 lua_createtable(L, 0, 1); /* create metatable for strings */
849 lua_pushliteral(L, ""); /* dummy string */
850 lua_pushvalue(L, -2);
851 lua_setmetatable(L, -2); /* set string metatable */
852 lua_pop(L, 1); /* pop dummy string */
853 lua_pushvalue(L, -2); /* string library... */
854 lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
855 lua_pop(L, 1); /* pop metatable */
856}
LUA_API int lua_setmetatable(lua_State *L, int objindex)
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
#define lua_pushliteral(L, s)

References lua_createtable(), lua_pop, lua_pushliteral, lua_pushvalue(), lua_setfield(), and lua_setmetatable().

Referenced by luaopen_string().

◆ end_capture()

static const char * end_capture ( MatchState * ms,
const char * s,
const char * p )
static

Definition at line 343 of file lua-5.1.5/src/lstrlib.c.

344 {
345 int l = capture_to_close(ms);
346 const char *res;
347 ms->capture[l].len = s - ms->capture[l].init; /* close capture */
348 if ((res = match(ms, s, p)) == NULL) /* match failed? */
349 ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
350 return res;
351}
#define NULL
Definition gmacros.h:924
static const char * match(MatchState *ms, const char *s, const char *p)
static int capture_to_close(MatchState *ms)

References CAP_UNFINISHED, MatchState::capture, capture_to_close(), MatchState::init, MatchState::len, match(), NULL, and s.

Referenced by match().

◆ gfind_nodef()

static int gfind_nodef ( lua_State * L)
static

Definition at line 584 of file lua-5.1.5/src/lstrlib.c.

584 {
585 return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
586 LUA_QL("string.gmatch"));
587}

References LUA_QL, and luaL_error().

◆ gmatch()

static int gmatch ( lua_State * L)
static

Definition at line 574 of file lua-5.1.5/src/lstrlib.c.

574 {
575 luaL_checkstring(L, 1);
576 luaL_checkstring(L, 2);
577 lua_settop(L, 2);
578 lua_pushinteger(L, 0);
580 return 1;
581}
LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n)
LUA_API void lua_settop(lua_State *L, int idx)
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
#define luaL_checkstring(L, n)
static int gmatch_aux(lua_State *L)

References gmatch_aux(), lua_pushcclosure(), lua_pushinteger(), lua_settop(), and luaL_checkstring.

◆ gmatch_aux()

static int gmatch_aux ( lua_State * L)
static

Definition at line 548 of file lua-5.1.5/src/lstrlib.c.

548 {
549 MatchState ms;
550 size_t ls;
551 const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
552 const char *p = lua_tostring(L, lua_upvalueindex(2));
553 const char *src;
554 ms.L = L;
555 ms.src_init = s;
556 ms.src_end = s+ls;
557 for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
558 src <= ms.src_end;
559 src++) {
560 const char *e;
561 ms.level = 0;
562 if ((e = match(&ms, src, p)) != NULL) {
563 lua_Integer newstart = e-s;
564 if (e == src) newstart++; /* empty match? go at least one position */
565 lua_pushinteger(L, newstart);
567 return push_captures(&ms, src, e);
568 }
569 }
570 return 0; /* not found */
571}
LUA_INTEGER lua_Integer
#define lua_upvalueindex(i)
#define lua_tostring(L, i)
#define lua_tointeger(L, i)
#define lua_replace(L, idx)
const char * src_init
const char * src_end

References MatchState::L, MatchState::level, lua_pushinteger(), lua_replace, lua_tointeger, lua_tolstring(), lua_tostring, lua_upvalueindex, match(), NULL, push_captures(), s, MatchState::src_end, and MatchState::src_init.

Referenced by gmatch().

◆ lmemfind()

static const char * lmemfind ( const char * s1,
size_t l1,
const char * s2,
size_t l2 )
static

Definition at line 444 of file lua-5.1.5/src/lstrlib.c.

445 {
446 if (l2 == 0) return s1; /* empty strings are everywhere */
447 else if (l2 > l1) return NULL; /* avoids a negative `l1' */
448 else {
449 const char *init; /* to search for a `*s2' inside `s1' */
450 l2--; /* 1st char will be checked by `memchr' */
451 l1 = l1-l2; /* `s2' cannot be found after that */
452 while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
453 init++; /* 1st char is already checked */
454 if (memcmp(init, s2+1, l2) == 0)
455 return init-1;
456 else { /* correct `l1' and `s1' to try again */
457 l1 -= init-s1;
458 s1 = init;
459 }
460 }
461 return NULL; /* not found */
462 }
463}

References NULL.

Referenced by str_find_aux().

◆ luaopen_string()

LUALIB_API int luaopen_string ( lua_State * L)

Definition at line 862 of file lua-5.1.5/src/lstrlib.c.

862 {
864#if defined(LUA_COMPAT_GFIND)
865 lua_getfield(L, -1, "gmatch");
866 lua_setfield(L, -2, "gfind");
867#endif
869 return 1;
870}
LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
LUALIB_API void luaL_register(lua_State *L, const char *libname, const luaL_Reg *l)
static void createmetatable(lua_State *L)
static const luaL_Reg strlib[]
#define LUA_STRLIBNAME

References createmetatable(), lua_getfield(), lua_setfield(), LUA_STRLIBNAME, luaL_register(), and strlib.

◆ match()

static const char * match ( MatchState * ms,
const char * s,
const char * p )
static

Definition at line 365 of file lua-5.1.5/src/lstrlib.c.

365 {
366 init: /* using goto's to optimize tail recursion */
367 switch (*p) {
368 case '(': { /* start capture */
369 if (*(p+1) == ')') /* position capture? */
370 return start_capture(ms, s, p+2, CAP_POSITION);
371 else
372 return start_capture(ms, s, p+1, CAP_UNFINISHED);
373 }
374 case ')': { /* end capture */
375 return end_capture(ms, s, p+1);
376 }
377 case L_ESC: {
378 switch (*(p+1)) {
379 case 'b': { /* balanced string? */
380 s = matchbalance(ms, s, p+2);
381 if (s == NULL) return NULL;
382 p+=4; goto init; /* else return match(ms, s, p+4); */
383 }
384 case 'f': { /* frontier? */
385 const char *ep; char previous;
386 p += 2;
387 if (*p != '[')
388 luaL_error(ms->L, "missing " LUA_QL("[") " after "
389 LUA_QL("%%f") " in pattern");
390 ep = classend(ms, p); /* points to what is next */
391 previous = (s == ms->src_init) ? '\0' : *(s-1);
392 if (matchbracketclass(uchar(previous), p, ep-1) ||
393 !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
394 p=ep; goto init; /* else return match(ms, s, ep); */
395 }
396 default: {
397 if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
398 s = match_capture(ms, s, uchar(*(p+1)));
399 if (s == NULL) return NULL;
400 p+=2; goto init; /* else return match(ms, s, p+2) */
401 }
402 goto dflt; /* case default */
403 }
404 }
405 }
406 case '\0': { /* end of pattern */
407 return s; /* match succeeded */
408 }
409 case '$': {
410 if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
411 return (s == ms->src_end) ? s : NULL; /* check end of string */
412 else goto dflt;
413 }
414 default: dflt: { /* it is a pattern item */
415 const char *ep = classend(ms, p); /* points to what is next */
416 int m = s<ms->src_end && singlematch(uchar(*s), p, ep);
417 switch (*ep) {
418 case '?': { /* optional */
419 const char *res;
420 if (m && ((res=match(ms, s+1, ep+1)) != NULL))
421 return res;
422 p=ep+1; goto init; /* else return match(ms, s, ep+1); */
423 }
424 case '*': { /* 0 or more repetitions */
425 return max_expand(ms, s, p, ep);
426 }
427 case '+': { /* 1 or more repetitions */
428 return (m ? max_expand(ms, s+1, p, ep) : NULL);
429 }
430 case '-': { /* 0 or more repetitions (minimum) */
431 return min_expand(ms, s, p, ep);
432 }
433 default: {
434 if (!m) return NULL;
435 s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
436 }
437 }
438 }
439 }
440}
static int singlematch(int c, const char *p, const char *ep)
static const char * match_capture(MatchState *ms, const char *s, int l)
static int matchbracketclass(int c, const char *p, const char *ec)
static const char * max_expand(MatchState *ms, const char *s, const char *p, const char *ep)
static const char * end_capture(MatchState *ms, const char *s, const char *p)
#define CAP_POSITION
static const char * matchbalance(MatchState *ms, const char *s, const char *p)
static const char * min_expand(MatchState *ms, const char *s, const char *p, const char *ep)
static const char * classend(MatchState *ms, const char *p)
static const char * start_capture(MatchState *ms, const char *s, const char *p, int what)

References CAP_POSITION, CAP_UNFINISHED, classend(), end_capture(), MatchState::L, L_ESC, LUA_QL, luaL_error(), match(), match_capture(), matchbalance(), matchbracketclass(), max_expand(), min_expand(), NULL, s, singlematch(), MatchState::src_end, MatchState::src_init, start_capture(), and uchar.

Referenced by duk__lookup_active_label(), duk__match_regexp(), duk__regexp_match_helper(), end_capture(), gmatch_aux(), match(), matchQuality(), max_expand(), min_expand(), start_capture(), str_find_aux(), and str_gsub().

◆ match_capture()

static const char * match_capture ( MatchState * ms,
const char * s,
int l )
static

Definition at line 354 of file lua-5.1.5/src/lstrlib.c.

354 {
355 size_t len;
356 l = check_capture(ms, l);
357 len = ms->capture[l].len;
358 if ((size_t)(ms->src_end-s) >= len &&
359 memcmp(ms->capture[l].init, s, len) == 0)
360 return s+len;
361 else return NULL;
362}
static int check_capture(MatchState *ms, int l)

References MatchState::capture, check_capture(), MatchState::init, MatchState::len, NULL, s, and MatchState::src_end.

Referenced by match().

◆ match_class()

static int match_class ( int c,
int cl )
static

Definition at line 226 of file lua-5.1.5/src/lstrlib.c.

226 {
227 int res;
228 switch (tolower(cl)) {
229 case 'a' : res = isalpha(c); break;
230 case 'c' : res = iscntrl(c); break;
231 case 'd' : res = isdigit(c); break;
232 case 'l' : res = islower(c); break;
233 case 'p' : res = ispunct(c); break;
234 case 's' : res = isspace(c); break;
235 case 'u' : res = isupper(c); break;
236 case 'w' : res = isalnum(c); break;
237 case 'x' : res = isxdigit(c); break;
238 case 'z' : res = (c == 0); break;
239 default: return (cl == c);
240 }
241 return (islower(cl) ? res : !res);
242}

Referenced by matchbracketclass(), and singlematch().

◆ matchbalance()

static const char * matchbalance ( MatchState * ms,
const char * s,
const char * p )
static

Definition at line 281 of file lua-5.1.5/src/lstrlib.c.

282 {
283 if (*p == 0 || *(p+1) == 0)
284 luaL_error(ms->L, "unbalanced pattern");
285 if (*s != *p) return NULL;
286 else {
287 int b = *p;
288 int e = *(p+1);
289 int cont = 1;
290 while (++s < ms->src_end) {
291 if (*s == e) {
292 if (--cont == 0) return s+1;
293 }
294 else if (*s == b) cont++;
295 }
296 }
297 return NULL; /* string ends out of balance */
298}

References MatchState::L, luaL_error(), NULL, and s.

Referenced by match().

◆ matchbracketclass()

static int matchbracketclass ( int c,
const char * p,
const char * ec )
static

Definition at line 245 of file lua-5.1.5/src/lstrlib.c.

245 {
246 int sig = 1;
247 if (*(p+1) == '^') {
248 sig = 0;
249 p++; /* skip the `^' */
250 }
251 while (++p < ec) {
252 if (*p == L_ESC) {
253 p++;
254 if (match_class(c, uchar(*p)))
255 return sig;
256 }
257 else if ((*(p+1) == '-') && (p+2 < ec)) {
258 p+=2;
259 if (uchar(*(p-2)) <= c && c <= uchar(*p))
260 return sig;
261 }
262 else if (uchar(*p) == c) return sig;
263 }
264 return !sig;
265}
static int match_class(int c, int cl)

References L_ESC, match_class(), and uchar.

Referenced by match(), and singlematch().

◆ max_expand()

static const char * max_expand ( MatchState * ms,
const char * s,
const char * p,
const char * ep )
static

Definition at line 301 of file lua-5.1.5/src/lstrlib.c.

302 {
303 ptrdiff_t i = 0; /* counts maximum expand for item */
304 while ((s+i)<ms->src_end && singlematch(uchar(*(s+i)), p, ep))
305 i++;
306 /* keeps trying to match with the maximum repetitions */
307 while (i>=0) {
308 const char *res = match(ms, (s+i), ep+1);
309 if (res) return res;
310 i--; /* else didn't match; reduce 1 repetition to try again */
311 }
312 return NULL;
313}

References match(), NULL, s, singlematch(), MatchState::src_end, and uchar.

Referenced by match().

◆ min_expand()

static const char * min_expand ( MatchState * ms,
const char * s,
const char * p,
const char * ep )
static

Definition at line 316 of file lua-5.1.5/src/lstrlib.c.

317 {
318 for (;;) {
319 const char *res = match(ms, s, ep+1);
320 if (res != NULL)
321 return res;
322 else if (s<ms->src_end && singlematch(uchar(*s), p, ep))
323 s++; /* try with one more repetition */
324 else return NULL;
325 }
326}

References match(), NULL, s, singlematch(), and uchar.

Referenced by match().

◆ posrelat()

static ptrdiff_t posrelat ( ptrdiff_t pos,
size_t len )
static

Definition at line 36 of file lua-5.1.5/src/lstrlib.c.

36 {
37 /* relative string position: negative means back from end */
38 if (pos < 0) pos += (ptrdiff_t)len + 1;
39 return (pos >= 0) ? pos : 0;
40}

Referenced by str_byte(), str_find_aux(), and str_sub().

◆ push_captures()

static int push_captures ( MatchState * ms,
const char * s,
const char * e )
static

Definition at line 485 of file lua-5.1.5/src/lstrlib.c.

485 {
486 int i;
487 int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
488 luaL_checkstack(ms->L, nlevels, "too many captures");
489 for (i = 0; i < nlevels; i++)
490 push_onecapture(ms, i, s, e);
491 return nlevels; /* number of strings pushed */
492}
LUALIB_API void luaL_checkstack(lua_State *L, int space, const char *mes)

References MatchState::L, MatchState::level, luaL_checkstack(), push_onecapture(), and s.

Referenced by add_value(), gmatch_aux(), and str_find_aux().

◆ push_onecapture()

static void push_onecapture ( MatchState * ms,
int i,
const char * s,
const char * e )
static

Definition at line 466 of file lua-5.1.5/src/lstrlib.c.

467 {
468 if (i >= ms->level) {
469 if (i == 0) /* ms->level == 0, too */
470 lua_pushlstring(ms->L, s, e - s); /* add whole match */
471 else
472 luaL_error(ms->L, "invalid capture index");
473 }
474 else {
475 ptrdiff_t l = ms->capture[i].len;
476 if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
477 if (l == CAP_POSITION)
478 lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
479 else
480 lua_pushlstring(ms->L, ms->capture[i].init, l);
481 }
482}

References CAP_POSITION, CAP_UNFINISHED, MatchState::capture, MatchState::init, MatchState::L, MatchState::len, MatchState::level, lua_pushinteger(), lua_pushlstring(), luaL_error(), s, and MatchState::src_init.

Referenced by add_s(), add_value(), and push_captures().

◆ scanformat()

static const char * scanformat ( lua_State * L,
const char * strfrmt,
char * form )
static

Definition at line 725 of file lua-5.1.5/src/lstrlib.c.

725 {
726 const char *p = strfrmt;
727 while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
728 if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
729 luaL_error(L, "invalid format (repeated flags)");
730 if (isdigit(uchar(*p))) p++; /* skip width */
731 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
732 if (*p == '.') {
733 p++;
734 if (isdigit(uchar(*p))) p++; /* skip precision */
735 if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
736 }
737 if (isdigit(uchar(*p)))
738 luaL_error(L, "invalid format (width or precision too long)");
739 *(form++) = '%';
740 strncpy(form, strfrmt, p - strfrmt + 1);
741 form += p - strfrmt + 1;
742 *form = '\0';
743 return p;
744}
#define FLAGS

References FLAGS, luaL_error(), NULL, and uchar.

Referenced by str_format().

◆ singlematch()

static int singlematch ( int c,
const char * p,
const char * ep )
static

Definition at line 268 of file lua-5.1.5/src/lstrlib.c.

268 {
269 switch (*p) {
270 case '.': return 1; /* matches any char */
271 case L_ESC: return match_class(c, uchar(*(p+1)));
272 case '[': return matchbracketclass(c, p, ep-1);
273 default: return (uchar(*p) == c);
274 }
275}

References L_ESC, match_class(), matchbracketclass(), and uchar.

Referenced by match(), max_expand(), and min_expand().

◆ start_capture()

static const char * start_capture ( MatchState * ms,
const char * s,
const char * p,
int what )
static

Definition at line 329 of file lua-5.1.5/src/lstrlib.c.

330 {
331 const char *res;
332 int level = ms->level;
333 if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
334 ms->capture[level].init = s;
335 ms->capture[level].len = what;
336 ms->level = level+1;
337 if ((res=match(ms, s, p)) == NULL) /* match failed? */
338 ms->level--; /* undo capture */
339 return res;
340}
#define LUA_MAXCAPTURES

References MatchState::capture, MatchState::init, MatchState::L, MatchState::len, MatchState::level, LUA_MAXCAPTURES, luaL_error(), match(), NULL, and s.

Referenced by match().

◆ str_byte()

static int str_byte ( lua_State * L)
static

Definition at line 106 of file lua-5.1.5/src/lstrlib.c.

106 {
107 size_t l;
108 const char *s = luaL_checklstring(L, 1, &l);
109 ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
110 ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
111 int n, i;
112 if (posi <= 0) posi = 1;
113 if ((size_t)pose > l) pose = l;
114 if (posi > pose) return 0; /* empty interval; return no values */
115 n = (int)(pose - posi + 1);
116 if (posi + n <= pose) /* overflow? */
117 luaL_error(L, "string slice too long");
118 luaL_checkstack(L, n, "string slice too long");
119 for (i=0; i<n; i++)
120 lua_pushinteger(L, uchar(s[posi+i-1]));
121 return n;
122}
LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int narg, lua_Integer def)
static ptrdiff_t posrelat(ptrdiff_t pos, size_t len)

References lua_pushinteger(), luaL_checklstring(), luaL_checkstack(), luaL_error(), luaL_optinteger(), posrelat(), s, and uchar.

◆ str_char()

static int str_char ( lua_State * L)
static

Definition at line 125 of file lua-5.1.5/src/lstrlib.c.

125 {
126 int n = lua_gettop(L); /* number of arguments */
127 int i;
128 luaL_Buffer b;
129 luaL_buffinit(L, &b);
130 for (i=1; i<=n; i++) {
131 int c = luaL_checkint(L, i);
132 luaL_argcheck(L, uchar(c) == c, i, "invalid value");
133 luaL_addchar(&b, uchar(c));
134 }
135 luaL_pushresult(&b);
136 return 1;
137}
LUA_API int lua_gettop(lua_State *L)
LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B)
LUALIB_API void luaL_pushresult(luaL_Buffer *B)
#define luaL_checkint(L, n)
#define luaL_argcheck(L, cond, numarg, extramsg)

References lua_gettop(), luaL_addchar, luaL_argcheck, luaL_buffinit(), luaL_checkint, luaL_pushresult(), and uchar.

◆ str_dump()

static int str_dump ( lua_State * L)
static

Definition at line 147 of file lua-5.1.5/src/lstrlib.c.

147 {
148 luaL_Buffer b;
150 lua_settop(L, 1);
151 luaL_buffinit(L,&b);
152 if (lua_dump(L, writer, &b) != 0)
153 luaL_error(L, "unable to dump given function");
154 luaL_pushresult(&b);
155 return 1;
156}
LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data)
LUALIB_API void luaL_checktype(lua_State *L, int narg, int t)
static int writer(lua_State *L, const void *b, size_t size, void *B)

References lua_dump(), lua_settop(), LUA_TFUNCTION, luaL_buffinit(), luaL_checktype(), luaL_error(), luaL_pushresult(), and writer().

◆ str_find()

static int str_find ( lua_State * L)
static

Definition at line 538 of file lua-5.1.5/src/lstrlib.c.

538 {
539 return str_find_aux(L, 1);
540}
static int str_find_aux(lua_State *L, int find)

References str_find_aux().

◆ str_find_aux()

static int str_find_aux ( lua_State * L,
int find )
static

Definition at line 495 of file lua-5.1.5/src/lstrlib.c.

495 {
496 size_t l1, l2;
497 const char *s = luaL_checklstring(L, 1, &l1);
498 const char *p = luaL_checklstring(L, 2, &l2);
499 ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
500 if (init < 0) init = 0;
501 else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
502 if (find && (lua_toboolean(L, 4) || /* explicit request? */
503 strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
504 /* do a plain search */
505 const char *s2 = lmemfind(s+init, l1-init, p, l2);
506 if (s2) {
507 lua_pushinteger(L, s2-s+1);
508 lua_pushinteger(L, s2-s+l2);
509 return 2;
510 }
511 }
512 else {
513 MatchState ms;
514 int anchor = (*p == '^') ? (p++, 1) : 0;
515 const char *s1=s+init;
516 ms.L = L;
517 ms.src_init = s;
518 ms.src_end = s+l1;
519 do {
520 const char *res;
521 ms.level = 0;
522 if ((res=match(&ms, s1, p)) != NULL) {
523 if (find) {
524 lua_pushinteger(L, s1-s+1); /* start */
525 lua_pushinteger(L, res-s); /* end */
526 return push_captures(&ms, NULL, 0) + 2;
527 }
528 else
529 return push_captures(&ms, s1, res);
530 }
531 } while (s1++ < ms.src_end && !anchor);
532 }
533 lua_pushnil(L); /* not found */
534 return 1;
535}
static size_t find(const char *s, const char *pattern, size_t start)
Definition LuaXML_lib.c:77
LUA_API void lua_pushnil(lua_State *L)
static const char * lmemfind(const char *s1, size_t l1, const char *s2, size_t l2)
#define SPECIALS

References find(), MatchState::L, MatchState::level, lmemfind(), lua_pushinteger(), lua_pushnil(), lua_toboolean(), luaL_checklstring(), luaL_optinteger(), match(), NULL, posrelat(), push_captures(), s, SPECIALS, MatchState::src_end, and MatchState::src_init.

Referenced by str_find(), and str_match().

◆ str_format()

static int str_format ( lua_State * L)
static

Definition at line 756 of file lua-5.1.5/src/lstrlib.c.

756 {
757 int top = lua_gettop(L);
758 int arg = 1;
759 size_t sfl;
760 const char *strfrmt = luaL_checklstring(L, arg, &sfl);
761 const char *strfrmt_end = strfrmt+sfl;
762 luaL_Buffer b;
763 luaL_buffinit(L, &b);
764 while (strfrmt < strfrmt_end) {
765 if (*strfrmt != L_ESC)
766 luaL_addchar(&b, *strfrmt++);
767 else if (*++strfrmt == L_ESC)
768 luaL_addchar(&b, *strfrmt++); /* %% */
769 else { /* format item */
770 char form[MAX_FORMAT]; /* to store the format (`%...') */
771 char buff[MAX_ITEM]; /* to store the formatted item */
772 if (++arg > top)
773 luaL_argerror(L, arg, "no value");
774 strfrmt = scanformat(L, strfrmt, form);
775 switch (*strfrmt++) {
776 case 'c': {
777 sprintf(buff, form, (int)luaL_checknumber(L, arg));
778 break;
779 }
780 case 'd': case 'i': {
781 addintlen(form);
782 sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
783 break;
784 }
785 case 'o': case 'u': case 'x': case 'X': {
786 addintlen(form);
787 sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
788 break;
789 }
790 case 'e': case 'E': case 'f':
791 case 'g': case 'G': {
792 sprintf(buff, form, (double)luaL_checknumber(L, arg));
793 break;
794 }
795 case 'q': {
796 addquoted(L, &b, arg);
797 continue; /* skip the 'addsize' at the end */
798 }
799 case 's': {
800 size_t l;
801 const char *s = luaL_checklstring(L, arg, &l);
802 if (!strchr(form, '.') && l >= 100) {
803 /* no precision and string is too long to be formatted;
804 keep original string */
805 lua_pushvalue(L, arg);
806 luaL_addvalue(&b);
807 continue; /* skip the `addsize' at the end */
808 }
809 else {
810 sprintf(buff, form, s);
811 break;
812 }
813 }
814 default: { /* also treat cases `pnLlh' */
815 return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
816 LUA_QL("format"), *(strfrmt - 1));
817 }
818 }
819 luaL_addlstring(&b, buff, strlen(buff));
820 }
821 }
822 luaL_pushresult(&b);
823 return 1;
824}
LUALIB_API int luaL_argerror(lua_State *L, int narg, const char *extramsg)
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg)
#define MAX_ITEM
#define MAX_FORMAT
static const char * scanformat(lua_State *L, const char *strfrmt, char *form)
static void addquoted(lua_State *L, luaL_Buffer *b, int arg)
static void addintlen(char *form)
#define LUA_INTFRM_T

References addintlen(), addquoted(), arg, L_ESC, lua_gettop(), LUA_INTFRM_T, lua_pushvalue(), LUA_QL, luaL_addchar, luaL_addlstring(), luaL_addvalue(), luaL_argerror(), luaL_buffinit(), luaL_checklstring(), luaL_checknumber(), luaL_error(), luaL_pushresult(), MAX_FORMAT, MAX_ITEM, s, and scanformat().

◆ str_gsub()

static int str_gsub ( lua_State * L)
static

Definition at line 644 of file lua-5.1.5/src/lstrlib.c.

644 {
645 size_t srcl;
646 const char *src = luaL_checklstring(L, 1, &srcl);
647 const char *p = luaL_checkstring(L, 2);
648 int tr = lua_type(L, 3);
649 int max_s = luaL_optint(L, 4, srcl+1);
650 int anchor = (*p == '^') ? (p++, 1) : 0;
651 int n = 0;
652 MatchState ms;
653 luaL_Buffer b;
654 luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
655 tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
656 "string/function/table expected");
657 luaL_buffinit(L, &b);
658 ms.L = L;
659 ms.src_init = src;
660 ms.src_end = src+srcl;
661 while (n < max_s) {
662 const char *e;
663 ms.level = 0;
664 e = match(&ms, src, p);
665 if (e) {
666 n++;
667 add_value(&ms, &b, src, e);
668 }
669 if (e && e>src) /* non empty match? */
670 src = e; /* skip it */
671 else if (src < ms.src_end)
672 luaL_addchar(&b, *src++);
673 else break;
674 if (anchor) break;
675 }
676 luaL_addlstring(&b, src, ms.src_end-src);
677 luaL_pushresult(&b);
678 lua_pushinteger(L, n); /* number of substitutions */
679 return 2;
680}
#define luaL_optint(L, n, d)
static void add_value(MatchState *ms, luaL_Buffer *b, const char *s, const char *e)

References add_value(), MatchState::L, MatchState::level, lua_pushinteger(), LUA_TFUNCTION, LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, lua_type(), luaL_addchar, luaL_addlstring(), luaL_argcheck, luaL_buffinit(), luaL_checklstring(), luaL_checkstring, luaL_optint, luaL_pushresult(), match(), MatchState::src_end, and MatchState::src_init.

◆ str_len()

static int str_len ( lua_State * L)
static

Definition at line 28 of file lua-5.1.5/src/lstrlib.c.

28 {
29 size_t l;
30 luaL_checklstring(L, 1, &l);
31 lua_pushinteger(L, l);
32 return 1;
33}

References lua_pushinteger(), and luaL_checklstring().

Referenced by duk_bi_nodejs_buffer_write().

◆ str_lower()

static int str_lower ( lua_State * L)
static

Definition at line 68 of file lua-5.1.5/src/lstrlib.c.

68 {
69 size_t l;
70 size_t i;
72 const char *s = luaL_checklstring(L, 1, &l);
73 luaL_buffinit(L, &b);
74 for (i=0; i<l; i++)
75 luaL_addchar(&b, tolower(uchar(s[i])));
77 return 1;
78}

References luaL_addchar, luaL_buffinit(), luaL_checklstring(), luaL_pushresult(), s, and uchar.

◆ str_match()

static int str_match ( lua_State * L)
static

Definition at line 543 of file lua-5.1.5/src/lstrlib.c.

543 {
544 return str_find_aux(L, 0);
545}

References str_find_aux().

◆ str_rep()

static int str_rep ( lua_State * L)
static

Definition at line 93 of file lua-5.1.5/src/lstrlib.c.

93 {
94 size_t l;
96 const char *s = luaL_checklstring(L, 1, &l);
97 int n = luaL_checkint(L, 2);
98 luaL_buffinit(L, &b);
99 while (n-- > 0)
100 luaL_addlstring(&b, s, l);
101 luaL_pushresult(&b);
102 return 1;
103}

References luaL_addlstring(), luaL_buffinit(), luaL_checkint, luaL_checklstring(), luaL_pushresult(), and s.

◆ str_reverse()

static int str_reverse ( lua_State * L)
static

Definition at line 57 of file lua-5.1.5/src/lstrlib.c.

57 {
58 size_t l;
60 const char *s = luaL_checklstring(L, 1, &l);
61 luaL_buffinit(L, &b);
62 while (l--) luaL_addchar(&b, s[l]);
64 return 1;
65}

References luaL_addchar, luaL_buffinit(), luaL_checklstring(), luaL_pushresult(), and s.

◆ str_sub()

static int str_sub ( lua_State * L)
static

Definition at line 43 of file lua-5.1.5/src/lstrlib.c.

43 {
44 size_t l;
45 const char *s = luaL_checklstring(L, 1, &l);
46 ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
47 ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
48 if (start < 1) start = 1;
49 if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
50 if (start <= end)
51 lua_pushlstring(L, s+start-1, end-start+1);
52 else lua_pushliteral(L, "");
53 return 1;
54}
LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg)

References lua_pushliteral, lua_pushlstring(), luaL_checkinteger(), luaL_checklstring(), luaL_optinteger(), posrelat(), and s.

◆ str_upper()

static int str_upper ( lua_State * L)
static

Definition at line 81 of file lua-5.1.5/src/lstrlib.c.

81 {
82 size_t l;
83 size_t i;
85 const char *s = luaL_checklstring(L, 1, &l);
86 luaL_buffinit(L, &b);
87 for (i=0; i<l; i++)
88 luaL_addchar(&b, toupper(uchar(s[i])));
90 return 1;
91}

References luaL_addchar, luaL_buffinit(), luaL_checklstring(), luaL_pushresult(), s, and uchar.

◆ writer()

static int writer ( lua_State * L,
const void * b,
size_t size,
void * B )
static

Definition at line 140 of file lua-5.1.5/src/lstrlib.c.

140 {
141 (void)L;
142 luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
143 return 0;
144}

References luaL_addlstring().

Referenced by lua_dump(), lua_dump(), str_dump(), vdbeIncrPopulate(), and vdbeSorterListToPMA().

Variable Documentation

◆ strlib

const luaL_Reg strlib[]
static
Initial value:
= {
{"byte", str_byte},
{"char", str_char},
{"dump", str_dump},
{"find", str_find},
{"format", str_format},
{"gfind", gfind_nodef},
{"gmatch", gmatch},
{"gsub", str_gsub},
{"len", str_len},
{"lower", str_lower},
{"match", str_match},
{"rep", str_rep},
{"reverse", str_reverse},
{"sub", str_sub},
{"upper", str_upper},
}
static int str_sub(lua_State *L)
static int str_len(lua_State *L)
static int str_find(lua_State *L)
static int str_upper(lua_State *L)
static int str_char(lua_State *L)
static int str_gsub(lua_State *L)
static int str_reverse(lua_State *L)
static int str_match(lua_State *L)
static int gfind_nodef(lua_State *L)
static int str_lower(lua_State *L)
static int gmatch(lua_State *L)
static int str_dump(lua_State *L)
static int str_rep(lua_State *L)
static int str_format(lua_State *L)
static int str_byte(lua_State *L)

Definition at line 827 of file lua-5.1.5/src/lstrlib.c.

827 {
828 {"byte", str_byte},
829 {"char", str_char},
830 {"dump", str_dump},
831 {"find", str_find},
832 {"format", str_format},
833 {"gfind", gfind_nodef},
834 {"gmatch", gmatch},
835 {"gsub", str_gsub},
836 {"len", str_len},
837 {"lower", str_lower},
838 {"match", str_match},
839 {"rep", str_rep},
840 {"reverse", str_reverse},
841 {"sub", str_sub},
842 {"upper", str_upper},
843 {NULL, NULL}
844};

Referenced by luaopen_string().