summaryrefslogtreecommitdiff
path: root/clients/lib/strlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'clients/lib/strlib.c')
-rw-r--r--clients/lib/strlib.c210
1 files changed, 147 insertions, 63 deletions
diff --git a/clients/lib/strlib.c b/clients/lib/strlib.c
index 0f37ab85..6a99871c 100644
--- a/clients/lib/strlib.c
+++ b/clients/lib/strlib.c
@@ -3,12 +3,13 @@
** String library to LUA
*/
-char *rcs_strlib="$Id: strlib.c,v 1.14 1995/11/10 17:54:31 roberto Exp $";
+char *rcs_strlib="$Id: strlib.c,v 1.23 1996/04/30 21:13:55 roberto Exp $";
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
+#include <limits.h>
#include "lua.h"
#include "lualib.h"
@@ -24,12 +25,12 @@ void lua_arg_error(char *funcname)
char *lua_check_string (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
- if (!(lua_isstring(o) || lua_isnumber(o)))
+ if (!lua_isstring(o))
lua_arg_error(funcname);
return lua_getstring(o);
}
-float lua_check_number (int numArg, char *funcname)
+double lua_check_number (int numArg, char *funcname)
{
lua_Object o = lua_getparam(numArg);
if (!lua_isnumber(o))
@@ -37,13 +38,36 @@ float lua_check_number (int numArg, char *funcname)
return lua_getnumber(o);
}
-static char *newstring (char *s)
+static int lua_opt_number (int numArg, int def, char *funcname)
{
- char *ns = (char *)malloc(strlen(s)+1);
- if (ns == 0)
- lua_error("not enough memory for new string");
- strcpy(ns, s);
- return ns;
+ return (lua_getparam(numArg) == LUA_NOOBJECT) ? def :
+ (int)lua_check_number(numArg, funcname);
+}
+
+char *luaI_addchar (int c)
+{
+ static char *buff = NULL;
+ static int max = 0;
+ static int n = 0;
+ if (n >= max)
+ {
+ if (max == 0)
+ {
+ max = 100;
+ buff = (char *)malloc(max);
+ }
+ else
+ {
+ max *= 2;
+ buff = (char *)realloc(buff, max);
+ }
+ if (buff == NULL)
+ lua_error("memory overflow");
+ }
+ buff[n++] = c;
+ if (c == 0)
+ n = 0; /* prepare for next string */
+ return buff;
}
@@ -56,15 +80,12 @@ static void str_find (void)
{
char *s1 = lua_check_string(1, "strfind");
char *s2 = lua_check_string(2, "strfind");
- int init = (lua_getparam(3) == LUA_NOOBJECT) ? 0 :
- (int)lua_check_number(3, "strfind")-1;
- char *f = strstr(s1+init,s2);
+ int init = lua_opt_number(3, 1, "strfind") - 1;
+ char *f = (init>=0 && init<=strlen(s1)) ? strstr(s1+init,s2) : NULL;
if (f != NULL)
{
int pos = f-s1+1;
- if (lua_getparam (4) == LUA_NOOBJECT)
- lua_pushnumber (pos);
- else if ((int)lua_check_number(4, "strfind") >= pos+strlen(s2)-1)
+ if (lua_opt_number(4, INT_MAX, "strfind") >= pos+strlen(s2)-1)
lua_pushnumber (pos);
else
lua_pushnil();
@@ -94,34 +115,16 @@ static void str_sub (void)
{
char *s = lua_check_string(1, "strsub");
int start = (int)lua_check_number(2, "strsub");
- int end = (lua_getparam(3) == LUA_NOOBJECT) ? strlen(s) :
- (int)lua_check_number(3, "strsub");
+ int end = lua_opt_number(3, strlen(s), "strsub");
if (end < start || start < 1 || end > strlen(s))
lua_pushliteral("");
else
{
- char temp = s[end];
- s[end] = 0;
- lua_pushstring (&s[start-1]);
- s[end] = temp;
- }
-}
-
-/*
-** Convert a string according to given function.
-*/
-typedef int (*strfunc)(int s);
-static void str_apply (strfunc f, char *funcname)
-{
- char *s, *c;
- c = s = newstring(lua_check_string(1, funcname));
- while (*c != 0)
- {
- *c = f(*c);
- c++;
+ luaI_addchar(0);
+ while (start <= end)
+ luaI_addchar(s[start++ - 1]);
+ lua_pushstring (luaI_addchar(0));
}
- lua_pushstring(s);
- free(s);
}
/*
@@ -131,7 +134,11 @@ static void str_apply (strfunc f, char *funcname)
*/
static void str_lower (void)
{
- str_apply(tolower, "strlower");
+ char *s = lua_check_string(1, "strlower");
+ luaI_addchar(0);
+ while (*s)
+ luaI_addchar(tolower(*s++));
+ lua_pushstring(luaI_addchar(0));
}
@@ -142,7 +149,11 @@ static void str_lower (void)
*/
static void str_upper (void)
{
- str_apply(toupper, "strupper");
+ char *s = lua_check_string(1, "strupper");
+ luaI_addchar(0);
+ while (*s)
+ luaI_addchar(toupper(*s++));
+ lua_pushstring(luaI_addchar(0));
}
/*
@@ -151,42 +162,115 @@ static void str_upper (void)
static void str_ascii (void)
{
char *s = lua_check_string(1, "ascii");
- lua_Object o2 = lua_getparam(2);
- int pos;
- pos = (o2 == LUA_NOOBJECT) ? 0 : (int)lua_check_number(2, "ascii")-1;
+ int pos = lua_opt_number(2, 1, "ascii") - 1;
if (pos<0 || pos>=strlen(s))
lua_arg_error("ascii");
lua_pushnumber(s[pos]);
}
-/*
-** converts one or more integers to chars in a string
-*/
-#define maxparams 50
-static void str_int2str (void)
+void luaI_addquoted (char *s)
+{
+ luaI_addchar('"');
+ for (; *s; s++)
+ {
+ if (*s == '"' || *s == '\\' || *s == '\n')
+ luaI_addchar('\\');
+ luaI_addchar(*s);
+ }
+ luaI_addchar('"');
+}
+
+#define MAX_CONVERTION 2000
+#define MAX_FORMAT 50
+
+static void str_format (void)
{
- char s[maxparams+1];
- int i = 0;
- while (lua_getparam(++i) != LUA_NOOBJECT)
+ int arg = 1;
+ char *strfrmt = lua_check_string(arg++, "format");
+ luaI_addchar(0); /* initialize */
+ while (*strfrmt)
{
- if (i > maxparams)
- lua_error("too many parameters to function `int2str'");
- s[i-1] = (int)lua_check_number(i, "int2str");
+ if (*strfrmt != '%')
+ luaI_addchar(*strfrmt++);
+ else if (*++strfrmt == '%')
+ luaI_addchar(*strfrmt++); /* %% */
+ else
+ { /* format item */
+ char form[MAX_FORMAT]; /* store the format ('%...') */
+ char buff[MAX_CONVERTION]; /* store the formated value */
+ int size = 0;
+ int i = 0;
+ form[i++] = '%';
+ form[i] = *strfrmt++;
+ while (!isalpha(form[i]))
+ {
+ if (isdigit(form[i]))
+ {
+ size = size*10 + form[i]-'0';
+ if (size >= MAX_CONVERTION)
+ lua_error("format size/precision too long in function `format'");
+ }
+ else if (form[i] == '.')
+ size = 0; /* re-start */
+ if (++i >= MAX_FORMAT)
+ lua_error("bad format in function `format'");
+ form[i] = *strfrmt++;
+ }
+ form[i+1] = 0; /* ends string */
+ switch (form[i])
+ {
+ case 'q':
+ luaI_addquoted(lua_check_string(arg++, "format"));
+ buff[0] = '\0'; /* addchar already done */
+ break;
+ case 's':
+ {
+ char *s = lua_check_string(arg++, "format");
+ if (strlen(s) >= MAX_CONVERTION)
+ lua_error("string argument too long in function `format'");
+ sprintf(buff, form, s);
+ break;
+ }
+ case 'c': case 'd': case 'i': case 'o':
+ case 'u': case 'x': case 'X':
+ sprintf(buff, form, (int)lua_check_number(arg++, "format"));
+ break;
+ case 'e': case 'E': case 'f': case 'g':
+ sprintf(buff, form, lua_check_number(arg++, "format"));
+ break;
+ default: /* also treat cases 'pnLlh' */
+ lua_error("invalid format option in function `format'");
+ }
+ for (i=0; buff[i]; i++) /* move formated value to result */
+ luaI_addchar(buff[i]);
+ }
}
- s[i-1] = 0;
- lua_pushstring(s);
+ lua_pushstring(luaI_addchar(0)); /* push the result */
}
+
+void luaI_openlib (struct lua_reg *l, int n)
+{
+ int i;
+ for (i=0; i<n; i++)
+ lua_register(l[i].name, l[i].func);
+}
+
+static struct lua_reg strlib[] = {
+{"strfind", str_find},
+{"strlen", str_len},
+{"strsub", str_sub},
+{"strlower", str_lower},
+{"strupper", str_upper},
+{"ascii", str_ascii},
+{"format", str_format}
+};
+
+
/*
** Open string library
*/
void strlib_open (void)
{
- lua_register ("strfind", str_find);
- lua_register ("strlen", str_len);
- lua_register ("strsub", str_sub);
- lua_register ("strlower", str_lower);
- lua_register ("strupper", str_upper);
- lua_register ("ascii", str_ascii);
- lua_register ("int2str", str_int2str);
+ luaI_openlib(strlib, (sizeof(strlib)/sizeof(strlib[0])));
}