?? lstrlib.c
字號(hào):
/*** $Id: lstrlib.c,v 1.1 2002/02/14 10:46:59 jcatki Exp $** Standard library for string operations and pattern-matching** See Copyright Notice in lua.h*/#include <ctype.h>#include <stddef.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "lua.h"#include "lauxlib.h"#include "lualib.h"static int str_len (lua_State *L) { size_t l; luaL_check_lstr(L, 1, &l); lua_pushnumber(L, l); return 1;}static long posrelat (long pos, size_t len) { /* relative string position: negative means back from end */ return (pos>=0) ? pos : (long)len+pos+1;}static int str_sub (lua_State *L) { size_t l; const char *s = luaL_check_lstr(L, 1, &l); long start = posrelat(luaL_check_long(L, 2), l); long end = posrelat(luaL_opt_long(L, 3, -1), l); if (start < 1) start = 1; if (end > (long)l) end = l; if (start <= end) lua_pushlstring(L, s+start-1, end-start+1); else lua_pushstring(L, ""); return 1;}static int str_lower (lua_State *L) { size_t l; size_t i; luaL_Buffer b; const char *s = luaL_check_lstr(L, 1, &l); luaL_buffinit(L, &b); for (i=0; i<l; i++) luaL_putchar(&b, tolower((unsigned char)(s[i]))); luaL_pushresult(&b); return 1;}static int str_upper (lua_State *L) { size_t l; size_t i; luaL_Buffer b; const char *s = luaL_check_lstr(L, 1, &l); luaL_buffinit(L, &b); for (i=0; i<l; i++) luaL_putchar(&b, toupper((unsigned char)(s[i]))); luaL_pushresult(&b); return 1;}static int str_rep (lua_State *L) { size_t l; luaL_Buffer b; const char *s = luaL_check_lstr(L, 1, &l); int n = luaL_check_int(L, 2); luaL_buffinit(L, &b); while (n-- > 0) luaL_addlstring(&b, s, l); luaL_pushresult(&b); return 1;}static int str_byte (lua_State *L) { size_t l; const char *s = luaL_check_lstr(L, 1, &l); long pos = posrelat(luaL_opt_long(L, 2, 1), l); luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2, "out of range"); lua_pushnumber(L, (unsigned char)s[pos-1]); return 1;}static int str_char (lua_State *L) { int n = lua_gettop(L); /* number of arguments */ int i; luaL_Buffer b; luaL_buffinit(L, &b); for (i=1; i<=n; i++) { int c = luaL_check_int(L, i); luaL_arg_check(L, (unsigned char)c == c, i, "invalid value"); luaL_putchar(&b, (unsigned char)c); } luaL_pushresult(&b); return 1;}/*** {======================================================** PATTERN MATCHING** =======================================================*/#ifndef MAX_CAPTURES#define MAX_CAPTURES 32 /* arbitrary limit */#endifstruct Capture { const char *src_end; /* end ('\0') of source string */ int level; /* total number of captures (finished or unfinished) */ struct { const char *init; long len; /* -1 signals unfinished capture */ } capture[MAX_CAPTURES];};#define ESC '%'#define SPECIALS "^$*+?.([%-"static int check_capture (lua_State *L, int l, struct Capture *cap) { l -= '1'; if (!(0 <= l && l < cap->level && cap->capture[l].len != -1)) lua_error(L, "invalid capture index"); return l;}static int capture_to_close (lua_State *L, struct Capture *cap) { int level = cap->level; for (level--; level>=0; level--) if (cap->capture[level].len == -1) return level; lua_error(L, "invalid pattern capture"); return 0; /* to avoid warnings */}const char *luaI_classend (lua_State *L, const char *p) { switch (*p++) { case ESC: if (*p == '\0') lua_error(L, "malformed pattern (ends with `%')"); return p+1; case '[': if (*p == '^') p++; do { /* look for a ']' */ if (*p == '\0') lua_error(L, "malformed pattern (missing `]')"); if (*(p++) == ESC && *p != '\0') p++; /* skip escapes (e.g. '%]') */ } while (*p != ']'); return p+1; default: return p; }}static int match_class (int c, int cl) { int res; switch (tolower(cl)) { case 'a' : res = isalpha(c); break; case 'c' : res = iscntrl(c); break; case 'd' : res = isdigit(c); break; case 'l' : res = islower(c); break; case 'p' : res = ispunct(c); break; case 's' : res = isspace(c); break; case 'u' : res = isupper(c); break; case 'w' : res = isalnum(c); break; case 'x' : res = isxdigit(c); break; case 'z' : res = (c == '\0'); break; default: return (cl == c); } return (islower(cl) ? res : !res);}static int matchbracketclass (int c, const char *p, const char *endclass) { int sig = 1; if (*(p+1) == '^') { sig = 0; p++; /* skip the '^' */ } while (++p < endclass) { if (*p == ESC) { p++; if (match_class(c, (unsigned char)*p)) return sig; } else if ((*(p+1) == '-') && (p+2 < endclass)) { p+=2; if ((int)(unsigned char)*(p-2) <= c && c <= (int)(unsigned char)*p) return sig; } else if ((int)(unsigned char)*p == c) return sig; } return !sig;}int luaI_singlematch (int c, const char *p, const char *ep) { switch (*p) { case '.': /* matches any char */ return 1; case ESC: return match_class(c, (unsigned char)*(p+1)); case '[': return matchbracketclass(c, p, ep-1); default: return ((unsigned char)*p == c); }}static const char *match (lua_State *L, const char *s, const char *p, struct Capture *cap);static const char *matchbalance (lua_State *L, const char *s, const char *p, struct Capture *cap) { if (*p == 0 || *(p+1) == 0) lua_error(L, "unbalanced pattern"); if (*s != *p) return NULL; else { int b = *p; int e = *(p+1); int cont = 1; while (++s < cap->src_end) { if (*s == e) { if (--cont == 0) return s+1; } else if (*s == b) cont++; } } return NULL; /* string ends out of balance */}static const char *max_expand (lua_State *L, const char *s, const char *p, const char *ep, struct Capture *cap) { long i = 0; /* counts maximum expand for item */ while ((s+i)<cap->src_end && luaI_singlematch((unsigned char)*(s+i), p, ep)) i++; /* keeps trying to match with the maximum repetitions */ while (i>=0) { const char *res = match(L, (s+i), ep+1, cap); if (res) return res; i--; /* else didn't match; reduce 1 repetition to try again */ } return NULL;}static const char *min_expand (lua_State *L, const char *s, const char *p, const char *ep, struct Capture *cap) { for (;;) { const char *res = match(L, s, ep+1, cap); if (res != NULL) return res; else if (s<cap->src_end && luaI_singlematch((unsigned char)*s, p, ep)) s++; /* try with one more repetition */ else return NULL; }}static const char *start_capture (lua_State *L, const char *s, const char *p, struct Capture *cap) { const char *res; int level = cap->level; if (level >= MAX_CAPTURES) lua_error(L, "too many captures"); cap->capture[level].init = s; cap->capture[level].len = -1; cap->level = level+1; if ((res=match(L, s, p+1, cap)) == NULL) /* match failed? */ cap->level--; /* undo capture */ return res;}static const char *end_capture (lua_State *L, const char *s, const char *p, struct Capture *cap) { int l = capture_to_close(L, cap); const char *res; cap->capture[l].len = s - cap->capture[l].init; /* close capture */ if ((res = match(L, s, p+1, cap)) == NULL) /* match failed? */ cap->capture[l].len = -1; /* undo capture */ return res;}static const char *match_capture (lua_State *L, const char *s, int level, struct Capture *cap) { int l = check_capture(L, level, cap); size_t len = cap->capture[l].len;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -