mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
"strmap" replaced by "strupper" and "strlower" (that's what people will
use, anyway). "gsub" aceppts a function to give the replacement string.
This commit is contained in:
parent
5b9fbfa006
commit
c96ad1c945
165
strlib.c
165
strlib.c
@ -3,7 +3,7 @@
|
||||
** String library to LUA
|
||||
*/
|
||||
|
||||
char *rcs_strlib="$Id: strlib.c,v 1.26 1996/08/05 20:55:24 roberto Exp roberto $";
|
||||
char *rcs_strlib="$Id: strlib.c,v 1.27 1996/08/09 13:14:11 roberto Exp roberto $";
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -14,25 +14,32 @@ char *rcs_strlib="$Id: strlib.c,v 1.26 1996/08/05 20:55:24 roberto Exp roberto $
|
||||
#include "lualib.h"
|
||||
|
||||
|
||||
static char *buffer = NULL;
|
||||
static size_t maxbuff = 0;
|
||||
static size_t buff_size = 0;
|
||||
struct lbuff {
|
||||
char *b;
|
||||
size_t max;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static struct lbuff lbuffer = {NULL, 0, 0};
|
||||
|
||||
|
||||
static char *lua_strbuffer (unsigned long size)
|
||||
{
|
||||
if (size > maxbuff) {
|
||||
buffer = (buffer) ? realloc(buffer, maxbuff=size) : malloc(maxbuff=size);
|
||||
if (buffer == NULL)
|
||||
if (size > lbuffer.max) {
|
||||
/* ANSI "realloc" doesn't need this test, but some machines (Sun!)
|
||||
don't follow ANSI */
|
||||
lbuffer.b = (lbuffer.b) ? realloc(lbuffer.b, lbuffer.max=size) :
|
||||
malloc(lbuffer.max=size);
|
||||
if (lbuffer.b == NULL)
|
||||
lua_error("memory overflow");
|
||||
}
|
||||
return buffer;
|
||||
return lbuffer.b;
|
||||
}
|
||||
|
||||
static char *openspace (unsigned long size)
|
||||
{
|
||||
char *buff = lua_strbuffer(buff_size+size);
|
||||
return buff+buff_size;
|
||||
char *buff = lua_strbuffer(lbuffer.size+size);
|
||||
return buff+lbuffer.size;
|
||||
}
|
||||
|
||||
void lua_arg_check(int cond, char *funcname)
|
||||
@ -72,21 +79,25 @@ long lua_opt_number (int numArg, long def, char *funcname)
|
||||
|
||||
char *luaI_addchar (int c)
|
||||
{
|
||||
if (buff_size >= maxbuff)
|
||||
lua_strbuffer(maxbuff == 0 ? 100 : maxbuff*2);
|
||||
buffer[buff_size++] = c;
|
||||
if (lbuffer.size >= lbuffer.max)
|
||||
lua_strbuffer(lbuffer.max == 0 ? 100 : lbuffer.max*2);
|
||||
lbuffer.b[lbuffer.size++] = c;
|
||||
if (c == 0)
|
||||
buff_size = 0; /* prepare for next string */
|
||||
return buffer;
|
||||
lbuffer.size = 0; /* prepare for next string */
|
||||
return lbuffer.b;
|
||||
}
|
||||
|
||||
static void addnchar (char *s, int n)
|
||||
{
|
||||
char *b = openspace(n);
|
||||
strncpy(b, s, n);
|
||||
buff_size += n;
|
||||
lbuffer.size += n;
|
||||
}
|
||||
|
||||
static void addstr (char *s)
|
||||
{
|
||||
addnchar(s, strlen(s));
|
||||
}
|
||||
|
||||
/*
|
||||
** Interface to strtok
|
||||
@ -113,8 +124,6 @@ static void str_tok (void)
|
||||
|
||||
/*
|
||||
** Return the string length
|
||||
** LUA interface:
|
||||
** n = strlen (string)
|
||||
*/
|
||||
static void str_len (void)
|
||||
{
|
||||
@ -122,9 +131,7 @@ static void str_len (void)
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the substring of a string, from start to end
|
||||
** LUA interface:
|
||||
** substring = strsub (string, start, end)
|
||||
** Return the substring of a string
|
||||
*/
|
||||
static void str_sub (void)
|
||||
{
|
||||
@ -140,24 +147,26 @@ static void str_sub (void)
|
||||
}
|
||||
|
||||
/*
|
||||
** Transliterate a string
|
||||
** Convert a string to lower case.
|
||||
*/
|
||||
static void str_map (void)
|
||||
static void str_lower (void)
|
||||
{
|
||||
char *s = lua_check_string(1, "strmap");
|
||||
char *from = lua_check_string(2, "strmap");
|
||||
char *to = lua_opt_string(3, "", "strmap");
|
||||
long len = strlen(to);
|
||||
for (luaI_addchar(0); *s; s++) {
|
||||
char *f = strrchr(from, *s);
|
||||
if (f == NULL)
|
||||
luaI_addchar(*s);
|
||||
else {
|
||||
long pos = f-from;
|
||||
if (pos < len)
|
||||
luaI_addchar(to[pos]);
|
||||
}
|
||||
}
|
||||
char *s = lua_check_string(1, "strlower");
|
||||
luaI_addchar(0);
|
||||
while (*s)
|
||||
luaI_addchar(tolower(*s++));
|
||||
lua_pushstring(luaI_addchar(0));
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert a string to upper case.
|
||||
*/
|
||||
static void str_upper (void)
|
||||
{
|
||||
char *s = lua_check_string(1, "strupper");
|
||||
luaI_addchar(0);
|
||||
while (*s)
|
||||
luaI_addchar(toupper(*s++));
|
||||
lua_pushstring(luaI_addchar(0));
|
||||
}
|
||||
|
||||
@ -255,11 +264,13 @@ static int num_captures; /* only valid after a sucessful call to match */
|
||||
static void push_captures (void)
|
||||
{
|
||||
int i;
|
||||
luaI_addchar(0);
|
||||
for (i=0; i<num_captures; i++) {
|
||||
if (capture[i].len == -1) lua_error("unfinished capture");
|
||||
addnchar(capture[i].init, capture[i].len);
|
||||
lua_pushstring(luaI_addchar(0));
|
||||
int l = capture[i].len;
|
||||
char *buff = openspace(l+1);
|
||||
if (l == -1) lua_error("unfinished capture");
|
||||
strncpy(buff, capture[i].init, l);
|
||||
buff[l] = 0;
|
||||
lua_pushstring(buff);
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,18 +282,6 @@ static int check_cap (int l, int level)
|
||||
return l;
|
||||
}
|
||||
|
||||
static void add_s (char *newp)
|
||||
{
|
||||
while (*newp) {
|
||||
if (*newp != ESC || !isdigit(*++newp))
|
||||
luaI_addchar(*newp++);
|
||||
else {
|
||||
int l = check_cap(*newp++, num_captures);
|
||||
addnchar(capture[l].init, capture[l].len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int capture_to_close (int level)
|
||||
{
|
||||
for (level--; level>=0; level--)
|
||||
@ -376,12 +375,44 @@ static void str_find (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void str_s (void)
|
||||
static void add_s (lua_Object newp)
|
||||
{
|
||||
char *src = lua_check_string(1, "s");
|
||||
char *p = lua_check_string(2, "s");
|
||||
char *newp = lua_check_string(3, "s");
|
||||
int max_s = lua_opt_number(4, strlen(src), "s");
|
||||
if (lua_isstring(newp)) {
|
||||
char *news = lua_getstring(newp);
|
||||
while (*news) {
|
||||
if (*news != ESC || !isdigit(*++news))
|
||||
luaI_addchar(*news++);
|
||||
else {
|
||||
int l = check_cap(*news++, num_captures);
|
||||
addnchar(capture[l].init, capture[l].len);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lua_isfunction(newp)) {
|
||||
lua_Object res;
|
||||
struct lbuff oldbuff;
|
||||
lua_beginblock();
|
||||
push_captures();
|
||||
/* function may use lbuffer, so save it and create a new one */
|
||||
oldbuff = lbuffer;
|
||||
lbuffer.b = NULL; lbuffer.max = lbuffer.size = 0;
|
||||
lua_callfunction(newp);
|
||||
/* restore old buffer */
|
||||
free(lbuffer.b);
|
||||
lbuffer = oldbuff;
|
||||
res = lua_getresult(1);
|
||||
addstr(lua_isstring(res) ? lua_getstring(res) : "");
|
||||
lua_endblock();
|
||||
}
|
||||
else lua_error("incorrect argument to `gsub'");
|
||||
}
|
||||
|
||||
static void str_gsub (void)
|
||||
{
|
||||
char *src = lua_check_string(1, "gsub");
|
||||
char *p = lua_check_string(2, "gsub");
|
||||
lua_Object newp = lua_getparam(3);
|
||||
int max_s = lua_opt_number(4, strlen(src), "gsub");
|
||||
int anchor = (*p == '^') ? (p++, 1) : 0;
|
||||
int n = 0;
|
||||
luaI_addchar(0);
|
||||
@ -390,14 +421,14 @@ static void str_s (void)
|
||||
if ((e=match(src, p, 0)) == NULL)
|
||||
luaI_addchar(*src++);
|
||||
else {
|
||||
if (e == src) lua_error("empty pattern in substitution"); /* ??? */
|
||||
if (e == src) lua_error("empty pattern in substitution");
|
||||
add_s(newp);
|
||||
src = e;
|
||||
n++;
|
||||
}
|
||||
if (anchor) break;
|
||||
}
|
||||
addnchar(src, strlen(src));
|
||||
addstr(src);
|
||||
lua_pushstring(luaI_addchar(0));
|
||||
lua_pushnumber(n); /* number of substitutions */
|
||||
}
|
||||
@ -455,16 +486,17 @@ static void str_format (void)
|
||||
case 's': {
|
||||
char *s = lua_check_string(arg++, "format");
|
||||
buff = openspace(strlen(s));
|
||||
buff_size += sprintf(buff, form, s);
|
||||
lbuffer.size += sprintf(buff, form, s);
|
||||
break;
|
||||
}
|
||||
case 'c': case 'd': case 'i': case 'o':
|
||||
case 'u': case 'x': case 'X':
|
||||
buff_size += sprintf(buff, form,
|
||||
(int)lua_check_number(arg++, "format"));
|
||||
lbuffer.size += sprintf(buff, form,
|
||||
(int)lua_check_number(arg++, "format"));
|
||||
break;
|
||||
case 'e': case 'E': case 'f': case 'g':
|
||||
buff_size += sprintf(buff, form, lua_check_number(arg++, "format"));
|
||||
lbuffer.size += sprintf(buff, form,
|
||||
lua_check_number(arg++, "format"));
|
||||
break;
|
||||
default: /* also treat cases 'pnLlh' */
|
||||
lua_error("invalid format option in function `format'");
|
||||
@ -488,11 +520,12 @@ static struct lua_reg strlib[] = {
|
||||
{"strlen", str_len},
|
||||
{"strsub", str_sub},
|
||||
{"strset", str_set},
|
||||
{"strmap", str_map},
|
||||
{"strlower", str_lower},
|
||||
{"strupper", str_upper},
|
||||
{"ascii", str_ascii},
|
||||
{"format", str_format},
|
||||
{"strfind", str_find},
|
||||
{"gsub", str_s}
|
||||
{"gsub", str_gsub}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user