00001 /* 00002 ** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto 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 <stdio.h> 00010 #include <stdlib.h> 00011 #include <string.h> 00012 00013 #define lobject_c 00014 #define LUA_CORE 00015 00016 #include "lua.h" 00017 00018 #include "ldo.h" 00019 #include "lmem.h" 00020 #include "lobject.h" 00021 #include "lstate.h" 00022 #include "lstring.h" 00023 #include "lvm.h" 00024 00025 00026 00027 const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL}; 00028 00029 00030 /* 00031 ** converts an integer to a "floating point byte", represented as 00032 ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if 00033 ** eeeee != 0 and (xxx) otherwise. 00034 */ 00035 int luaO_int2fb (unsigned int x) { 00036 int e = 0; /* expoent */ 00037 while (x >= 16) { 00038 x = (x+1) >> 1; 00039 e++; 00040 } 00041 if (x < 8) return x; 00042 else return ((e+1) << 3) | (cast_int(x) - 8); 00043 } 00044 00045 00046 /* converts back */ 00047 int luaO_fb2int (int x) { 00048 int e = (x >> 3) & 31; 00049 if (e == 0) return x; 00050 else return ((x & 7)+8) << (e - 1); 00051 } 00052 00053 00054 int luaO_log2 (unsigned int x) { 00055 static const lu_byte log_2[256] = { 00056 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, 00057 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, 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 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, 00061 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, 00062 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, 00063 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 00064 }; 00065 int l = -1; 00066 while (x >= 256) { l += 8; x >>= 8; } 00067 return l + log_2[x]; 00068 00069 } 00070 00071 00072 int luaO_rawequalObj (const TValue *t1, const TValue *t2) { 00073 if (ttype(t1) != ttype(t2)) return 0; 00074 else switch (ttype(t1)) { 00075 case LUA_TNIL: 00076 return 1; 00077 case LUA_TNUMBER: 00078 return luai_numeq(nvalue(t1), nvalue(t2)); 00079 case LUA_TBOOLEAN: 00080 return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ 00081 case LUA_TLIGHTUSERDATA: 00082 return pvalue(t1) == pvalue(t2); 00083 default: 00084 lua_assert(iscollectable(t1)); 00085 return gcvalue(t1) == gcvalue(t2); 00086 } 00087 } 00088 00089 00090 int luaO_str2d (const char *s, lua_Number *result) { 00091 char *endptr; 00092 *result = lua_str2number(s, &endptr); 00093 if (endptr == s) return 0; /* conversion failed */ 00094 if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ 00095 *result = cast_num(strtoul(s, &endptr, 16)); 00096 if (*endptr == '\0') return 1; /* most common case */ 00097 while (isspace(cast(unsigned char, *endptr))) endptr++; 00098 if (*endptr != '\0') return 0; /* invalid trailing characters? */ 00099 return 1; 00100 } 00101 00102 00103 00104 static void pushstr (lua_State *L, const char *str) { 00105 setsvalue2s(L, L->top, luaS_new(L, str)); 00106 incr_top(L); 00107 } 00108 00109 00110 /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ 00111 const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 00112 int n = 1; 00113 pushstr(L, ""); 00114 for (;;) { 00115 const char *e = strchr(fmt, '%'); 00116 if (e == NULL) break; 00117 setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt)); 00118 incr_top(L); 00119 switch (*(e+1)) { 00120 case 's': { 00121 const char *s = va_arg(argp, char *); 00122 if (s == NULL) s = "(null)"; 00123 pushstr(L, s); 00124 break; 00125 } 00126 case 'c': { 00127 char buff[2]; 00128 buff[0] = cast(char, va_arg(argp, int)); 00129 buff[1] = '\0'; 00130 pushstr(L, buff); 00131 break; 00132 } 00133 case 'd': { 00134 setnvalue(L->top, cast_num(va_arg(argp, int))); 00135 incr_top(L); 00136 break; 00137 } 00138 case 'f': { 00139 setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); 00140 incr_top(L); 00141 break; 00142 } 00143 case 'p': { 00144 char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ 00145 sprintf(buff, "%p", va_arg(argp, void *)); 00146 pushstr(L, buff); 00147 break; 00148 } 00149 case '%': { 00150 pushstr(L, "%"); 00151 break; 00152 } 00153 default: { 00154 char buff[3]; 00155 buff[0] = '%'; 00156 buff[1] = *(e+1); 00157 buff[2] = '\0'; 00158 pushstr(L, buff); 00159 break; 00160 } 00161 } 00162 n += 2; 00163 fmt = e+2; 00164 } 00165 pushstr(L, fmt); 00166 luaV_concat(L, n+1, cast_int(L->top - L->base) - 1); 00167 L->top -= n; 00168 return svalue(L->top - 1); 00169 } 00170 00171 00172 const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { 00173 const char *msg; 00174 va_list argp; 00175 va_start(argp, fmt); 00176 msg = luaO_pushvfstring(L, fmt, argp); 00177 va_end(argp); 00178 return msg; 00179 } 00180 00181 00182 void luaO_chunkid (char *out, const char *source, size_t bufflen) { 00183 if (*source == '=') { 00184 strncpy(out, source+1, bufflen); /* remove first char */ 00185 out[bufflen-1] = '\0'; /* ensures null termination */ 00186 } 00187 else { /* out = "source", or "...source" */ 00188 if (*source == '@') { 00189 size_t l; 00190 source++; /* skip the `@' */ 00191 bufflen -= sizeof(" '...' "); 00192 l = strlen(source); 00193 strcpy(out, ""); 00194 if (l > bufflen) { 00195 source += (l-bufflen); /* get last part of file name */ 00196 strcat(out, "..."); 00197 } 00198 strcat(out, source); 00199 } 00200 else { /* out = [string "string"] */ 00201 size_t len = strcspn(source, "\n\r"); /* stop at first newline */ 00202 bufflen -= sizeof(" [string \"...\"] "); 00203 if (len > bufflen) len = bufflen; 00204 strcpy(out, "[string \""); 00205 if (source[len] != '\0') { /* must truncate? */ 00206 strncat(out, source, len); 00207 strcat(out, "..."); 00208 } 00209 else 00210 strcat(out, source); 00211 strcat(out, "\"]"); 00212 } 00213 } 00214 }
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:54 2011 by Doxygen 1.6.1