Lua 5.1.4: lobject.c


L0001    /*
L0002    ** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
L0003    ** Some generic functions over Lua objects
L0004    ** See Copyright Notice in lua.h
L0005    */
L0006    
L0007    #include <ctype.h>
L0008    #include <stdarg.h>
L0009    #include <stdio.h>
L0010    #include <stdlib.h>
L0011    #include <string.h>
L0012    
L0013    #define lobject_c
L0014    #define LUA_CORE
L0015    
L0016    #include "lua.h"
L0017    
L0018    #include "ldo.h"
L0019    #include "lmem.h"
L0020    #include "lobject.h"
L0021    #include "lstate.h"
L0022    #include "lstring.h"
L0023    #include "lvm.h"
L0024    
L0025    
L0026    
L0027    const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
L0028    
L0029    
L0030    /*
L0031    ** converts an integer to a "floating point byte", represented as
L0032    ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
L0033    ** eeeee != 0 and (xxx) otherwise.
L0034    */
L0035    int luaO_int2fb (unsigned int x) {
L0036      int e = 0;  /* expoent */
L0037      while (x >= 16) {
L0038        x = (x+1) >> 1;
L0039        e++;
L0040      }
L0041      if (x < 8) return x;
L0042      else return ((e+1) << 3) | (cast_int(x) - 8);
L0043    }
L0044    
L0045    
L0046    /* converts back */
L0047    int luaO_fb2int (int x) {
L0048      int e = (x >> 3) & 31;
L0049      if (e == 0) return x;
L0050      else return ((x & 7)+8) << (e - 1);
L0051    }
L0052    
L0053    
L0054    int luaO_log2 (unsigned int x) {
L0055      static const lu_byte log_2[256] = {
L0056        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,
L0057        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,
L0058        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,
L0059        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,
L0060        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,
L0061        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,
L0062        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,
L0063        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
L0064      };
L0065      int l = -1;
L0066      while (x >= 256) { l += 8; x >>= 8; }
L0067      return l + log_2[x];
L0068    
L0069    }
L0070    
L0071    
L0072    int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
L0073      if (ttype(t1) != ttype(t2)) return 0;
L0074      else switch (ttype(t1)) {
L0075        case LUA_TNIL:
L0076          return 1;
L0077        case LUA_TNUMBER:
L0078          return luai_numeq(nvalue(t1), nvalue(t2));
L0079        case LUA_TBOOLEAN:
L0080          return bvalue(t1) == bvalue(t2);  /* boolean true must be 1 !! */
L0081        case LUA_TLIGHTUSERDATA:
L0082          return pvalue(t1) == pvalue(t2);
L0083        default:
L0084          lua_assert(iscollectable(t1));
L0085          return gcvalue(t1) == gcvalue(t2);
L0086      }
L0087    }
L0088    
L0089    
L0090    int luaO_str2d (const char *s, lua_Number *result) {
L0091      char *endptr;
L0092      *result = lua_str2number(s, &endptr);
L0093      if (endptr == s) return 0;  /* conversion failed */
L0094      if (*endptr == 'x' || *endptr == 'X')  /* maybe an hexadecimal constant? */
L0095        *result = cast_num(strtoul(s, &endptr, 16));
L0096      if (*endptr == '\0') return 1;  /* most common case */
L0097      while (isspace(cast(unsigned char, *endptr))) endptr++;
L0098      if (*endptr != '\0') return 0;  /* invalid trailing characters? */
L0099      return 1;
L0100    }
L0101    
L0102    
L0103    
L0104    static void pushstr (lua_State *L, const char *str) {
L0105      setsvalue2s(L, L->top, luaS_new(L, str));
L0106      incr_top(L);
L0107    }
L0108    
L0109    
L0110    /* this function handles only `%d', `%c', %f, %p, and `%s' formats */
L0111    const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
L0112      int n = 1;
L0113      pushstr(L, "");
L0114      for (;;) {
L0115        const char *e = strchr(fmt, '%');
L0116        if (e == NULL) break;
L0117        setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
L0118        incr_top(L);
L0119        switch (*(e+1)) {
L0120          case 's': {
L0121            const char *s = va_arg(argp, char *);
L0122            if (s == NULL) s = "(null)";
L0123            pushstr(L, s);
L0124            break;
L0125          }
L0126          case 'c': {
L0127            char buff[2];
L0128            buff[0] = cast(char, va_arg(argp, int));
L0129            buff[1] = '\0';
L0130            pushstr(L, buff);
L0131            break;
L0132          }
L0133          case 'd': {
L0134            setnvalue(L->top, cast_num(va_arg(argp, int)));
L0135            incr_top(L);
L0136            break;
L0137          }
L0138          case 'f': {
L0139            setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
L0140            incr_top(L);
L0141            break;
L0142          }
L0143          case 'p': {
L0144            char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
L0145            sprintf(buff, "%p", va_arg(argp, void *));
L0146            pushstr(L, buff);
L0147            break;
L0148          }
L0149          case '%': {
L0150            pushstr(L, "%");
L0151            break;
L0152          }
L0153          default: {
L0154            char buff[3];
L0155            buff[0] = '%';
L0156            buff[1] = *(e+1);
L0157            buff[2] = '\0';
L0158            pushstr(L, buff);
L0159            break;
L0160          }
L0161        }
L0162        n += 2;
L0163        fmt = e+2;
L0164      }
L0165      pushstr(L, fmt);
L0166      luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
L0167      L->top -= n;
L0168      return svalue(L->top - 1);
L0169    }
L0170    
L0171    
L0172    const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
L0173      const char *msg;
L0174      va_list argp;
L0175      va_start(argp, fmt);
L0176      msg = luaO_pushvfstring(L, fmt, argp);
L0177      va_end(argp);
L0178      return msg;
L0179    }
L0180    
L0181    
L0182    void luaO_chunkid (char *out, const char *source, size_t bufflen) {
L0183      if (*source == '=') {
L0184        strncpy(out, source+1, bufflen);  /* remove first char */
L0185        out[bufflen-1] = '\0';  /* ensures null termination */
L0186      }
L0187      else {  /* out = "source", or "...source" */
L0188        if (*source == '@') {
L0189          size_t l;
L0190          source++;  /* skip the `@' */
L0191          bufflen -= sizeof(" '...' ");
L0192          l = strlen(source);
L0193          strcpy(out, "");
L0194          if (l > bufflen) {
L0195            source += (l-bufflen);  /* get last part of file name */
L0196            strcat(out, "...");
L0197          }
L0198          strcat(out, source);
L0199        }
L0200        else {  /* out = [string "string"] */
L0201          size_t len = strcspn(source, "\n\r");  /* stop at first newline */
L0202          bufflen -= sizeof(" [string \"...\"] ");
L0203          if (len > bufflen) len = bufflen;
L0204          strcpy(out, "[string \"");
L0205          if (source[len] != '\0') {  /* must truncate? */
L0206            strncat(out, source, len);
L0207            strcat(out, "...");
L0208          }
L0209          else
L0210            strcat(out, source);
L0211          strcat(out, "\"]");
L0212        }
L0213      }
L0214    }

Generated by pretty.lua