strlib.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. ** strlib.c
  3. ** String library to LUA
  4. */
  5. char *rcs_strlib="$Id: strlib.c,v 1.18 1996/02/12 18:32:40 roberto Exp $";
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <ctype.h>
  10. #include "lua.h"
  11. #include "lualib.h"
  12. void lua_arg_error(char *funcname)
  13. {
  14. char buff[100];
  15. sprintf(buff, "incorrect arguments to function `%s'", funcname);
  16. lua_error(buff);
  17. }
  18. char *lua_check_string (int numArg, char *funcname)
  19. {
  20. lua_Object o = lua_getparam(numArg);
  21. if (!(lua_isstring(o) || lua_isnumber(o)))
  22. lua_arg_error(funcname);
  23. return lua_getstring(o);
  24. }
  25. double lua_check_number (int numArg, char *funcname)
  26. {
  27. lua_Object o = lua_getparam(numArg);
  28. if (lua_isnumber(o))
  29. return lua_getnumber(o);
  30. else if (lua_isstring(o))
  31. {
  32. float t;
  33. char c;
  34. if (sscanf(lua_getstring(o), "%f %c",&t, &c) == 1)
  35. return t;
  36. }
  37. lua_arg_error(funcname);
  38. return 0; /* to avoid warnings */
  39. }
  40. char *luaI_addchar (int c)
  41. {
  42. static char *buff = NULL;
  43. static int max = 0;
  44. static int n = 0;
  45. if (n >= max)
  46. {
  47. if (max == 0)
  48. {
  49. max = 100;
  50. buff = (char *)malloc(max);
  51. }
  52. else
  53. {
  54. max *= 2;
  55. buff = (char *)realloc(buff, max);
  56. }
  57. if (buff == NULL)
  58. lua_error("memory overflow");
  59. }
  60. buff[n++] = c;
  61. if (c == 0)
  62. n = 0; /* prepare for next string */
  63. return buff;
  64. }
  65. /*
  66. ** Return the position of the first caracter of a substring into a string
  67. ** LUA interface:
  68. ** n = strfind (string, substring, init, end)
  69. */
  70. static void str_find (void)
  71. {
  72. char *s1 = lua_check_string(1, "strfind");
  73. char *s2 = lua_check_string(2, "strfind");
  74. int init = (lua_getparam(3) == LUA_NOOBJECT) ? 0 :
  75. (int)lua_check_number(3, "strfind")-1;
  76. char *f = strstr(s1+init,s2);
  77. if (f != NULL)
  78. {
  79. int pos = f-s1+1;
  80. if (lua_getparam (4) == LUA_NOOBJECT)
  81. lua_pushnumber (pos);
  82. else if ((int)lua_check_number(4, "strfind") >= pos+strlen(s2)-1)
  83. lua_pushnumber (pos);
  84. else
  85. lua_pushnil();
  86. }
  87. else
  88. lua_pushnil();
  89. }
  90. /*
  91. ** Return the string length
  92. ** LUA interface:
  93. ** n = strlen (string)
  94. */
  95. static void str_len (void)
  96. {
  97. char *s = lua_check_string(1, "strlen");
  98. lua_pushnumber(strlen(s));
  99. }
  100. /*
  101. ** Return the substring of a string, from start to end
  102. ** LUA interface:
  103. ** substring = strsub (string, start, end)
  104. */
  105. static void str_sub (void)
  106. {
  107. char *s = lua_check_string(1, "strsub");
  108. int start = (int)lua_check_number(2, "strsub");
  109. int end = (lua_getparam(3) == LUA_NOOBJECT) ? strlen(s) :
  110. (int)lua_check_number(3, "strsub");
  111. if (end < start || start < 1 || end > strlen(s))
  112. lua_pushliteral("");
  113. else
  114. {
  115. luaI_addchar(0);
  116. while (start <= end)
  117. luaI_addchar(s[start++ - 1]);
  118. lua_pushstring (luaI_addchar(0));
  119. }
  120. }
  121. /*
  122. ** Convert a string to lower case.
  123. ** LUA interface:
  124. ** lowercase = strlower (string)
  125. */
  126. static void str_lower (void)
  127. {
  128. char *s = lua_check_string(1, "strlower");
  129. luaI_addchar(0);
  130. while (*s)
  131. luaI_addchar(tolower(*s++));
  132. lua_pushstring(luaI_addchar(0));
  133. }
  134. /*
  135. ** Convert a string to upper case.
  136. ** LUA interface:
  137. ** uppercase = strupper (string)
  138. */
  139. static void str_upper (void)
  140. {
  141. char *s = lua_check_string(1, "strupper");
  142. luaI_addchar(0);
  143. while (*s)
  144. luaI_addchar(toupper(*s++));
  145. lua_pushstring(luaI_addchar(0));
  146. }
  147. /*
  148. ** get ascii value of a character in a string
  149. */
  150. static void str_ascii (void)
  151. {
  152. char *s = lua_check_string(1, "ascii");
  153. lua_Object o2 = lua_getparam(2);
  154. int pos;
  155. pos = (o2 == LUA_NOOBJECT) ? 0 : (int)lua_check_number(2, "ascii")-1;
  156. if (pos<0 || pos>=strlen(s))
  157. lua_arg_error("ascii");
  158. lua_pushnumber(s[pos]);
  159. }
  160. #define MAX_CONVERTION 2000
  161. #define MAX_FORMAT 50
  162. static void str_format (void)
  163. {
  164. int arg = 1;
  165. char *strfrmt = lua_check_string(arg++, "format");
  166. luaI_addchar(0); /* initialize */
  167. while (*strfrmt)
  168. {
  169. if (*strfrmt != '%')
  170. luaI_addchar(*strfrmt++);
  171. else if (*++strfrmt == '%')
  172. luaI_addchar(*strfrmt++); /* %% */
  173. else
  174. { /* format item */
  175. char form[MAX_FORMAT]; /* store the format ('%...') */
  176. char buff[MAX_CONVERTION]; /* store the formated value */
  177. int size = 0;
  178. int i = 0;
  179. form[i++] = '%';
  180. form[i] = *strfrmt++;
  181. while (!isalpha(form[i]))
  182. {
  183. if (isdigit(form[i]))
  184. {
  185. size = size*10 + form[i]-'0';
  186. if (size >= MAX_CONVERTION)
  187. lua_error("format size/precision too long in function `format'");
  188. }
  189. else if (form[i] == '.')
  190. size = 0; /* re-start */
  191. if (++i >= MAX_FORMAT)
  192. lua_error("bad format in function `format'");
  193. form[i] = *strfrmt++;
  194. }
  195. form[i+1] = 0; /* ends string */
  196. switch (form[i])
  197. {
  198. case 's':
  199. {
  200. char *s = lua_check_string(arg++, "format");
  201. if (strlen(s) >= MAX_CONVERTION)
  202. lua_error("string argument too long in function `format'");
  203. sprintf(buff, form, s);
  204. break;
  205. }
  206. case 'c': case 'd': case 'i': case 'o':
  207. case 'u': case 'x': case 'X':
  208. sprintf(buff, form, (int)lua_check_number(arg++, "format"));
  209. break;
  210. case 'e': case 'E': case 'f': case 'g':
  211. sprintf(buff, form, lua_check_number(arg++, "format"));
  212. break;
  213. default: /* also treat cases 'pnLlh' */
  214. lua_error("invalid format option in function `format'");
  215. }
  216. for (i=0; buff[i]; i++) /* move formated value to result */
  217. luaI_addchar(buff[i]);
  218. }
  219. }
  220. lua_pushstring(luaI_addchar(0)); /* push the result */
  221. }
  222. /*
  223. ** Open string library
  224. */
  225. void strlib_open (void)
  226. {
  227. lua_register ("strfind", str_find);
  228. lua_register ("strlen", str_len);
  229. lua_register ("strsub", str_sub);
  230. lua_register ("strlower", str_lower);
  231. lua_register ("strupper", str_upper);
  232. lua_register ("ascii", str_ascii);
  233. lua_register ("format", str_format);
  234. }