diff options
Diffstat (limited to 'lib/lua/src/lobject.c')
-rw-r--r-- | lib/lua/src/lobject.c | 134 |
1 files changed, 75 insertions, 59 deletions
diff --git a/lib/lua/src/lobject.c b/lib/lua/src/lobject.c index 62c70b6..0bfc9be 100644 --- a/lib/lua/src/lobject.c +++ b/lib/lua/src/lobject.c @@ -1,15 +1,17 @@ /* -** $Id: lobject.c,v 1.6 2004-12-19 16:14:04 pixel Exp $ +** $Id: lobject.c,v 1.7 2007-07-27 10:05:54 pixel Exp $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ #include <ctype.h> #include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> #define lobject_c +#define LUA_CORE #include "lua.h" @@ -20,57 +22,60 @@ #include "lstring.h" #include "lvm.h" -const TObject luaO_nilobject = {LUA_TNIL, {NULL}}; + + +const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; /* ** converts an integer to a "floating point byte", represented as -** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) +** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if +** eeeee != 0 and (xxx) otherwise. */ int luaO_int2fb (unsigned int x) { - int m = 0; /* mantissa */ - while (x >= (1<<3)) { + int e = 0; /* expoent */ + while (x >= 16) { x = (x+1) >> 1; - m++; + e++; } - return (m << 3) | cast(int, x); + if (x < 8) return x; + else return ((e+1) << 3) | (cast_int(x) - 8); +} + + +/* converts back */ +int luaO_fb2int (int x) { + int e = (x >> 3) & 31; + if (e == 0) return x; + else return ((x & 7)+8) << (e - 1); } int luaO_log2 (unsigned int x) { - static const lu_byte log_8[255] = { - 0, - 1,1, - 2,2,2,2, - 3,3,3,3,3,3,3,3, - 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 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, + static const lu_byte log_2[256] = { + 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, 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, 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, 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, - 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, - 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 + 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, + 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, + 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, + 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 }; - if (x >= 0x00010000) { - if (x >= 0x01000000) return log_8[((x>>24) & 0xff) - 1]+24; - else return log_8[((x>>16) & 0xff) - 1]+16; - } - else { - if (x >= 0x00000100) return log_8[((x>>8) & 0xff) - 1]+8; - else if (x) return log_8[(x & 0xff) - 1]; - return -1; /* special `log' for 0 */ - } + int l = -1; + while (x >= 256) { l += 8; x >>= 8; } + return l + log_2[x]; + } -int luaO_rawequalObj (const TObject *t1, const TObject *t2) { +int luaO_rawequalObj (const TValue *t1, const TValue *t2) { if (ttype(t1) != ttype(t2)) return 0; else switch (ttype(t1)) { case LUA_TNIL: return 1; case LUA_TNUMBER: - return nvalue(t1) == nvalue(t2); + return luai_numeq(nvalue(t1), nvalue(t2)); case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ case LUA_TLIGHTUSERDATA: @@ -84,45 +89,40 @@ int luaO_rawequalObj (const TObject *t1, const TObject *t2) { int luaO_str2d (const char *s, lua_Number *result) { char *endptr; - size_t l = strlen(s); - lua_Number res; - if ((l > 0) && (s[0] == '0') && (s[1] != '.')) { - if ((l > 2) && (s[1] == 'x')) { - res = strtol(s + 2, &endptr, 16); - } else { - res = strtol(s + 1, &endptr, 8); - } - } else { - res = strtod(s, &endptr); - } - if (endptr == s) return 0; /* no conversion */ - while (isspace((unsigned char)(*endptr))) endptr++; + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* conversion failed */ + if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ + *result = cast_num(strtoul(s, &endptr, 16)); + if (*endptr == '\0') return 1; /* most common case */ + while (isspace(cast(unsigned char, *endptr))) endptr++; if (*endptr != '\0') return 0; /* invalid trailing characters? */ - *result = res; return 1; } static void pushstr (lua_State *L, const char *str) { - setsvalue2s(L->top, luaS_new(L, str)); + setsvalue2s(L, L->top, luaS_new(L, str)); incr_top(L); } -/* this function handles only `%d', `%c', %f, and `%s' formats */ +/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { int n = 1; pushstr(L, ""); for (;;) { const char *e = strchr(fmt, '%'); if (e == NULL) break; - setsvalue2s(L->top, luaS_newlstr(L, fmt, e-fmt)); + setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); incr_top(L); switch (*(e+1)) { - case 's': - pushstr(L, va_arg(argp, char *)); + case 's': { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s); break; + } case 'c': { char buff[2]; buff[0] = cast(char, va_arg(argp, int)); @@ -130,24 +130,40 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { pushstr(L, buff); break; } - case 'd': - setnvalue(L->top, cast(lua_Number, va_arg(argp, int))); + case 'd': { + setnvalue(L->top, cast_num(va_arg(argp, int))); incr_top(L); break; - case 'f': - setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber))); + } + case 'f': { + setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); incr_top(L); break; - case '%': + } + case 'p': { + char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ + sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff); + break; + } + case '%': { pushstr(L, "%"); break; - default: lua_assert(0); + } + default: { + char buff[3]; + buff[0] = '%'; + buff[1] = *(e+1); + buff[2] = '\0'; + pushstr(L, buff); + break; + } } n += 2; fmt = e+2; } pushstr(L, fmt); - luaV_concat(L, n+1, L->top - L->base - 1); + luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); L->top -= n; return svalue(L->top - 1); } @@ -163,26 +179,26 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { } -void luaO_chunkid (char *out, const char *source, int bufflen) { +void luaO_chunkid (char *out, const char *source, size_t bufflen) { if (*source == '=') { strncpy(out, source+1, bufflen); /* remove first char */ out[bufflen-1] = '\0'; /* ensures null termination */ } else { /* out = "source", or "...source" */ if (*source == '@') { - int l; + size_t l; source++; /* skip the `@' */ - bufflen -= sizeof(" `...' "); + bufflen -= sizeof(" '...' "); l = strlen(source); strcpy(out, ""); - if (l>bufflen) { + if (l > bufflen) { source += (l-bufflen); /* get last part of file name */ strcat(out, "..."); } strcat(out, source); } else { /* out = [string "string"] */ - int len = strcspn(source, "\n"); /* stop at first newline */ + size_t len = strcspn(source, "\n\r"); /* stop at first newline */ bufflen -= sizeof(" [string \"...\"] "); if (len > bufflen) len = bufflen; strcpy(out, "[string \""); |