lobject.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. ** $Id: lobject.c,v 2.10 2005/03/08 20:10:05 roberto Exp roberto $
  3. ** Some generic functions over Lua objects
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <ctype.h>
  7. #include <stdarg.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #define lobject_c
  12. #define LUA_CORE
  13. #include "lua.h"
  14. #include "ldo.h"
  15. #include "lmem.h"
  16. #include "lobject.h"
  17. #include "lstate.h"
  18. #include "lstring.h"
  19. #include "lvm.h"
  20. const TValue luaO_nilobject = {{NULL}, LUA_TNIL};
  21. /*
  22. ** converts an integer to a "floating point byte", represented as
  23. ** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm)
  24. */
  25. int luaO_int2fb (unsigned int x) {
  26. int e = 0; /* expoent */
  27. while (x >= 16) {
  28. x = (x+1) >> 1;
  29. e++;
  30. }
  31. if (x < 8) return x;
  32. else return ((e+1) << 3) | (cast(int, x) - 8);
  33. }
  34. /* converts back */
  35. int luaO_fb2int (int x) {
  36. int e = (x >> 3) & 31;
  37. if (e == 0) return x;
  38. else return ((x & 7)+8) << (e - 1);
  39. }
  40. int luaO_log2 (unsigned int x) {
  41. static const lu_byte log_2[256] = {
  42. 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  43. 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  44. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  45. 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  46. 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  47. 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  48. 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  49. 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
  50. };
  51. int l = -1;
  52. while (x >= 256) { l += 8; x >>= 8; }
  53. return l + log_2[x];
  54. }
  55. int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
  56. if (ttype(t1) != ttype(t2)) return 0;
  57. else switch (ttype(t1)) {
  58. case LUA_TNIL:
  59. return 1;
  60. case LUA_TNUMBER:
  61. return luai_numeq(nvalue(t1), nvalue(t2));
  62. case LUA_TBOOLEAN:
  63. return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
  64. case LUA_TLIGHTUSERDATA:
  65. return pvalue(t1) == pvalue(t2);
  66. default:
  67. lua_assert(iscollectable(t1));
  68. return gcvalue(t1) == gcvalue(t2);
  69. }
  70. }
  71. int luaO_str2d (const char *s, lua_Number *result) {
  72. char *endptr;
  73. lua_Number res = lua_str2number(s, &endptr);
  74. if (endptr == s) return 0; /* no conversion */
  75. while (isspace(cast(unsigned char, *endptr))) endptr++;
  76. if (*endptr != '\0') return 0; /* invalid trailing characters? */
  77. *result = res;
  78. return 1;
  79. }
  80. static void pushstr (lua_State *L, const char *str) {
  81. setsvalue2s(L, L->top, luaS_new(L, str));
  82. incr_top(L);
  83. }
  84. /* this function handles only `%d', `%c', %f, %p, and `%s' formats */
  85. const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
  86. int n = 1;
  87. pushstr(L, "");
  88. for (;;) {
  89. const char *e = strchr(fmt, '%');
  90. if (e == NULL) break;
  91. setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
  92. incr_top(L);
  93. switch (*(e+1)) {
  94. case 's': {
  95. pushstr(L, va_arg(argp, char *));
  96. break;
  97. }
  98. case 'c': {
  99. char buff[2];
  100. buff[0] = cast(char, va_arg(argp, int));
  101. buff[1] = '\0';
  102. pushstr(L, buff);
  103. break;
  104. }
  105. case 'd': {
  106. setnvalue(L->top, cast(lua_Number, va_arg(argp, int)));
  107. incr_top(L);
  108. break;
  109. }
  110. case 'f': {
  111. setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber)));
  112. incr_top(L);
  113. break;
  114. }
  115. case 'p': {
  116. char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
  117. sprintf(buff, "%p", va_arg(argp, void *));
  118. pushstr(L, buff);
  119. break;
  120. }
  121. case '%': {
  122. pushstr(L, "%");
  123. break;
  124. }
  125. default: {
  126. char buff[3];
  127. buff[0] = '%';
  128. buff[1] = *(e+1);
  129. buff[2] = '\0';
  130. pushstr(L, buff);
  131. break;
  132. }
  133. }
  134. n += 2;
  135. fmt = e+2;
  136. }
  137. pushstr(L, fmt);
  138. luaV_concat(L, n+1, L->top - L->base - 1);
  139. L->top -= n;
  140. return svalue(L->top - 1);
  141. }
  142. const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
  143. const char *msg;
  144. va_list argp;
  145. va_start(argp, fmt);
  146. msg = luaO_pushvfstring(L, fmt, argp);
  147. va_end(argp);
  148. return msg;
  149. }
  150. void luaO_chunkid (char *out, const char *source, int bufflen) {
  151. if (*source == '=') {
  152. strncpy(out, source+1, bufflen); /* remove first char */
  153. out[bufflen-1] = '\0'; /* ensures null termination */
  154. }
  155. else { /* out = "source", or "...source" */
  156. if (*source == '@') {
  157. int l;
  158. source++; /* skip the `@' */
  159. bufflen -= sizeof(" `...' ");
  160. l = strlen(source);
  161. strcpy(out, "");
  162. if (l>bufflen) {
  163. source += (l-bufflen); /* get last part of file name */
  164. strcat(out, "...");
  165. }
  166. strcat(out, source);
  167. }
  168. else { /* out = [string "string"] */
  169. int len = strcspn(source, "\n\r"); /* stop at first newline */
  170. bufflen -= sizeof(" [string \"...\"] ");
  171. if (len > bufflen) len = bufflen;
  172. strcpy(out, "[string \"");
  173. if (source[len] != '\0') { /* must truncate? */
  174. strncat(out, source, len);
  175. strcat(out, "...");
  176. }
  177. else
  178. strcat(out, source);
  179. strcat(out, "\"]");
  180. }
  181. }
  182. }