/* ** strlib.c ** String library to LUA */ char *rcs_strlib="$Id: strlib.c,v 1.18 1996/02/12 18:34:44 roberto Exp roberto $"; #include #include #include #include #include "lua.h" #include "lualib.h" void lua_arg_error(char *funcname) { char buff[100]; sprintf(buff, "incorrect arguments to function `%s'", funcname); lua_error(buff); } char *lua_check_string (int numArg, char *funcname) { lua_Object o = lua_getparam(numArg); if (!(lua_isstring(o) || lua_isnumber(o))) lua_arg_error(funcname); return lua_getstring(o); } double lua_check_number (int numArg, char *funcname) { lua_Object o = lua_getparam(numArg); if (lua_isnumber(o)) return lua_getnumber(o); else if (lua_isstring(o)) { float t; char c; if (sscanf(lua_getstring(o), "%f %c",&t, &c) == 1) return t; } lua_arg_error(funcname); return 0; /* to avoid warnings */ } 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; } /* ** Return the position of the first caracter of a substring into a string ** LUA interface: ** n = strfind (string, substring, init, end) */ 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); 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) lua_pushnumber (pos); else lua_pushnil(); } else lua_pushnil(); } /* ** Return the string length ** LUA interface: ** n = strlen (string) */ static void str_len (void) { char *s = lua_check_string(1, "strlen"); lua_pushnumber(strlen(s)); } /* ** Return the substring of a string, from start to end ** LUA interface: ** substring = strsub (string, start, end) */ 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"); if (end < start || start < 1 || end > strlen(s)) lua_pushliteral(""); else { luaI_addchar(0); while (start <= end) luaI_addchar(s[start++ - 1]); lua_pushstring (luaI_addchar(0)); } } /* ** Convert a string to lower case. ** LUA interface: ** lowercase = strlower (string) */ 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. ** LUA interface: ** uppercase = strupper (string) */ 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)); } /* ** get ascii value of a character in a string */ 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; if (pos<0 || pos>=strlen(s)) lua_arg_error("ascii"); lua_pushnumber(s[pos]); } 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) { int arg = 1; char *strfrmt = lua_check_string(arg++, "format"); luaI_addchar(0); /* initialize */ while (*strfrmt) { 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]); } } lua_pushstring(luaI_addchar(0)); /* push the result */ } /* ** 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 ("format", str_format); }