/* ** strlib.c ** String library to LUA */ char *rcs_strlib="$Id: strlib.c,v 1.22 1996/03/22 17:57:24 roberto Exp roberto $"; #include #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_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)) lua_arg_error(funcname); return lua_getnumber(o); } static int lua_opt_number (int numArg, int def, char *funcname) { 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; } /* ** 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_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_opt_number(4, INT_MAX, "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_opt_number(3, strlen(s), "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"); int pos = lua_opt_number(2, 1, "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 */ } void luaI_openlib (struct lua_reg *l, int n) { int i; for (i=0; i