diff options
Diffstat (limited to 'clients/lib/strlib.c')
-rw-r--r-- | clients/lib/strlib.c | 210 |
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]))); } |