commit c96ad1c9455b59ea3ff25660549b0e2ad222791e
parent 5b9fbfa0066e86a8397c7f07a9596cb94d14e51b
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 16 Sep 1996 15:02:20 -0300
"strmap" replaced by "strupper" and "strlower" (that's what people will
use, anyway).
"gsub" aceppts a function to give the replacement string.
Diffstat:
M | strlib.c | | | 167 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
1 file changed, 100 insertions(+), 67 deletions(-)
diff --git a/strlib.c b/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)
-{
- 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]);
- }
- }
+static void str_lower (void)
+{
+ 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)
+{
+ 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, "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");
+ 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}
};