rpm
4.5
|
00001 /* 00002 ** $Id: lobject.c,v 1.1 2004/03/16 21:58:30 niemeyer Exp $ 00003 ** Some generic functions over Lua objects 00004 ** See Copyright Notice in lua.h 00005 */ 00006 00007 #include <ctype.h> 00008 #include <stdarg.h> 00009 #include <stdlib.h> 00010 #include <string.h> 00011 00012 #define lobject_c 00013 00014 #include "lua.h" 00015 00016 #include "ldo.h" 00017 #include "lmem.h" 00018 #include "lobject.h" 00019 #include "lstate.h" 00020 #include "lstring.h" 00021 #include "lvm.h" 00022 00023 00024 /* function to convert a string to a lua_Number */ 00025 #ifndef lua_str2number 00026 #define lua_str2number(s,p) strtod((s), (p)) 00027 #endif 00028 00029 00030 const TObject luaO_nilobject = {LUA_TNIL, {NULL}}; 00031 00032 00033 /* 00034 ** converts an integer to a "floating point byte", represented as 00035 ** (mmmmmxxx), where the real value is (xxx) * 2^(mmmmm) 00036 */ 00037 int luaO_int2fb (unsigned int x) { 00038 int m = 0; /* mantissa */ 00039 while (x >= (1<<3)) { 00040 x = (x+1) >> 1; 00041 m++; 00042 } 00043 return (m << 3) | cast(int, x); 00044 } 00045 00046 00047 int luaO_log2 (unsigned int x) { 00048 static const lu_byte log_8[255] = { 00049 0, 00050 1,1, 00051 2,2,2,2, 00052 3,3,3,3,3,3,3,3, 00053 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 00054 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, 00055 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, 00056 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, 00057 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, 00058 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, 00059 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, 00060 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 00061 }; 00062 if (x >= 0x00010000) { 00063 if (x >= 0x01000000) return log_8[((x>>24) & 0xff) - 1]+24; 00064 else return log_8[((x>>16) & 0xff) - 1]+16; 00065 } 00066 else { 00067 if (x >= 0x00000100) return log_8[((x>>8) & 0xff) - 1]+8; 00068 else if (x) return log_8[(x & 0xff) - 1]; 00069 return -1; /* special `log' for 0 */ 00070 } 00071 } 00072 00073 00074 int luaO_rawequalObj (const TObject *t1, const TObject *t2) { 00075 if (ttype(t1) != ttype(t2)) return 0; 00076 else switch (ttype(t1)) { 00077 case LUA_TNIL: 00078 return 1; 00079 case LUA_TNUMBER: 00080 return nvalue(t1) == nvalue(t2); 00081 case LUA_TBOOLEAN: 00082 return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ 00083 case LUA_TLIGHTUSERDATA: 00084 return pvalue(t1) == pvalue(t2); 00085 default: 00086 lua_assert(iscollectable(t1)); 00087 return gcvalue(t1) == gcvalue(t2); 00088 } 00089 } 00090 00091 00092 int luaO_str2d (const char *s, lua_Number *result) { 00093 char *endptr; 00094 lua_Number res = lua_str2number(s, &endptr); 00095 if (endptr == s) return 0; /* no conversion */ 00096 while (isspace((unsigned char)(*endptr))) endptr++; 00097 if (*endptr != '\0') return 0; /* invalid trailing characters? */ 00098 *result = res; 00099 return 1; 00100 } 00101 00102 00103 00104 static void pushstr (lua_State *L, const char *str) 00105 /*@modifies L @*/ 00106 { 00107 setsvalue2s(L->top, luaS_new(L, str)); 00108 incr_top(L); 00109 } 00110 00111 00112 /* this function handles only `%d', `%c', %f, and `%s' formats */ 00113 const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 00114 int n = 1; 00115 pushstr(L, ""); 00116 for (;;) { 00117 const char *e = strchr(fmt, '%'); 00118 if (e == NULL) break; 00119 setsvalue2s(L->top, luaS_newlstr(L, fmt, e-fmt)); 00120 incr_top(L); 00121 switch (*(e+1)) { 00122 case 's': 00123 pushstr(L, va_arg(argp, char *)); 00124 break; 00125 case 'c': { 00126 char buff[2]; 00127 buff[0] = cast(char, va_arg(argp, int)); 00128 buff[1] = '\0'; 00129 pushstr(L, buff); 00130 break; 00131 } 00132 case 'd': 00133 setnvalue(L->top, cast(lua_Number, va_arg(argp, int))); 00134 incr_top(L); 00135 break; 00136 case 'f': 00137 setnvalue(L->top, cast(lua_Number, va_arg(argp, l_uacNumber))); 00138 incr_top(L); 00139 break; 00140 case '%': 00141 pushstr(L, "%"); 00142 break; 00143 default: lua_assert(0); 00144 } 00145 n += 2; 00146 fmt = e+2; 00147 } 00148 pushstr(L, fmt); 00149 luaV_concat(L, n+1, L->top - L->base - 1); 00150 L->top -= n; 00151 return svalue(L->top - 1); 00152 } 00153 00154 00155 const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { 00156 const char *msg; 00157 va_list argp; 00158 va_start(argp, fmt); 00159 msg = luaO_pushvfstring(L, fmt, argp); 00160 va_end(argp); 00161 return msg; 00162 } 00163 00164 00165 void luaO_chunkid (char *out, const char *source, int bufflen) { 00166 if (*source == '=') { 00167 strncpy(out, source+1, bufflen); /* remove first char */ 00168 out[bufflen-1] = '\0'; /* ensures null termination */ 00169 } 00170 else { /* out = "source", or "...source" */ 00171 if (*source == '@') { 00172 int l; 00173 source++; /* skip the `@' */ 00174 bufflen -= sizeof(" `...' "); 00175 l = strlen(source); 00176 strcpy(out, ""); 00177 if (l>bufflen) { 00178 source += (l-bufflen); /* get last part of file name */ 00179 strcat(out, "..."); 00180 } 00181 strcat(out, source); 00182 } 00183 else { /* out = [string "string"] */ 00184 int len = strcspn(source, "\n"); /* stop at first newline */ 00185 bufflen -= sizeof(" [string \"...\"] "); 00186 if (len > bufflen) len = bufflen; 00187 strcpy(out, "[string \""); 00188 if (source[len] != '\0') { /* must truncate? */ 00189 strncat(out, source, len); 00190 strcat(out, "..."); 00191 } 00192 else 00193 strcat(out, source); 00194 strcat(out, "\"]"); 00195 } 00196 } 00197 }