lobject.c

Go to the documentation of this file.
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