2812
+ − 1
/*
+ − 2
** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
+ − 3
** Some generic functions over Lua objects
+ − 4
** See Copyright Notice in lua.h
+ − 5
*/
+ − 6
+ − 7
#include <ctype.h>
+ − 8
#include <stdarg.h>
+ − 9
#include <stdio.h>
+ − 10
#include <stdlib.h>
+ − 11
#include <string.h>
+ − 12
+ − 13
#define lobject_c
+ − 14
#define LUA_CORE
+ − 15
+ − 16
#include "lua.h"
+ − 17
+ − 18
#include "ldo.h"
+ − 19
#include "lmem.h"
+ − 20
#include "lobject.h"
+ − 21
#include "lstate.h"
+ − 22
#include "lstring.h"
+ − 23
#include "lvm.h"
+ − 24
+ − 25
+ − 26
+ − 27
const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
+ − 28
+ − 29
+ − 30
/*
+ − 31
** converts an integer to a "floating point byte", represented as
+ − 32
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
+ − 33
** eeeee != 0 and (xxx) otherwise.
+ − 34
*/
+ − 35
int luaO_int2fb (unsigned int x) {
+ − 36
int e = 0; /* expoent */
+ − 37
while (x >= 16) {
+ − 38
x = (x+1) >> 1;
+ − 39
e++;
+ − 40
}
+ − 41
if (x < 8) return x;
+ − 42
else return ((e+1) << 3) | (cast_int(x) - 8);
+ − 43
}
+ − 44
+ − 45
+ − 46
/* converts back */
+ − 47
int luaO_fb2int (int x) {
+ − 48
int e = (x >> 3) & 31;
+ − 49
if (e == 0) return x;
+ − 50
else return ((x & 7)+8) << (e - 1);
+ − 51
}
+ − 52
+ − 53
+ − 54
int luaO_log2 (unsigned int x) {
+ − 55
static const lu_byte log_2[256] = {
+ − 56
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,
+ − 57
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,
+ − 58
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,
+ − 59
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,
+ − 60
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,
+ − 61
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,
+ − 62
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,
+ − 63
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
+ − 64
};
+ − 65
int l = -1;
+ − 66
while (x >= 256) { l += 8; x >>= 8; }
+ − 67
return l + log_2[x];
+ − 68
+ − 69
}
+ − 70
+ − 71
+ − 72
int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
+ − 73
if (ttype(t1) != ttype(t2)) return 0;
+ − 74
else switch (ttype(t1)) {
+ − 75
case LUA_TNIL:
+ − 76
return 1;
+ − 77
case LUA_TNUMBER:
+ − 78
return luai_numeq(nvalue(t1), nvalue(t2));
+ − 79
case LUA_TBOOLEAN:
+ − 80
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
+ − 81
case LUA_TLIGHTUSERDATA:
+ − 82
return pvalue(t1) == pvalue(t2);
+ − 83
default:
+ − 84
lua_assert(iscollectable(t1));
+ − 85
return gcvalue(t1) == gcvalue(t2);
+ − 86
}
+ − 87
}
+ − 88
+ − 89
+ − 90
int luaO_str2d (const char *s, lua_Number *result) {
+ − 91
char *endptr;
+ − 92
*result = lua_str2number(s, &endptr);
+ − 93
if (endptr == s) return 0; /* conversion failed */
+ − 94
if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
+ − 95
*result = cast_num(strtoul(s, &endptr, 16));
+ − 96
if (*endptr == '\0') return 1; /* most common case */
+ − 97
while (isspace(cast(unsigned char, *endptr))) endptr++;
+ − 98
if (*endptr != '\0') return 0; /* invalid trailing characters? */
+ − 99
return 1;
+ − 100
}
+ − 101
+ − 102
+ − 103
+ − 104
static void pushstr (lua_State *L, const char *str) {
+ − 105
setsvalue2s(L, L->top, luaS_new(L, str));
+ − 106
incr_top(L);
+ − 107
}
+ − 108
+ − 109
+ − 110
/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
+ − 111
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
+ − 112
int n = 1;
+ − 113
pushstr(L, "");
+ − 114
for (;;) {
+ − 115
const char *e = strchr(fmt, '%');
+ − 116
if (e == NULL) break;
+ − 117
setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
+ − 118
incr_top(L);
+ − 119
switch (*(e+1)) {
+ − 120
case 's': {
+ − 121
const char *s = va_arg(argp, char *);
+ − 122
if (s == NULL) s = "(null)";
+ − 123
pushstr(L, s);
+ − 124
break;
+ − 125
}
+ − 126
case 'c': {
+ − 127
char buff[2];
+ − 128
buff[0] = cast(char, va_arg(argp, int));
+ − 129
buff[1] = '\0';
+ − 130
pushstr(L, buff);
+ − 131
break;
+ − 132
}
+ − 133
case 'd': {
+ − 134
setnvalue(L->top, cast_num(va_arg(argp, int)));
+ − 135
incr_top(L);
+ − 136
break;
+ − 137
}
+ − 138
case 'f': {
+ − 139
setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
+ − 140
incr_top(L);
+ − 141
break;
+ − 142
}
+ − 143
case 'p': {
+ − 144
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
+ − 145
sprintf(buff, "%p", va_arg(argp, void *));
+ − 146
pushstr(L, buff);
+ − 147
break;
+ − 148
}
+ − 149
case '%': {
+ − 150
pushstr(L, "%");
+ − 151
break;
+ − 152
}
+ − 153
default: {
+ − 154
char buff[3];
+ − 155
buff[0] = '%';
+ − 156
buff[1] = *(e+1);
+ − 157
buff[2] = '\0';
+ − 158
pushstr(L, buff);
+ − 159
break;
+ − 160
}
+ − 161
}
+ − 162
n += 2;
+ − 163
fmt = e+2;
+ − 164
}
+ − 165
pushstr(L, fmt);
+ − 166
luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
+ − 167
L->top -= n;
+ − 168
return svalue(L->top - 1);
+ − 169
}
+ − 170
+ − 171
+ − 172
const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
+ − 173
const char *msg;
+ − 174
va_list argp;
+ − 175
va_start(argp, fmt);
+ − 176
msg = luaO_pushvfstring(L, fmt, argp);
+ − 177
va_end(argp);
+ − 178
return msg;
+ − 179
}
+ − 180
+ − 181
+ − 182
void luaO_chunkid (char *out, const char *source, size_t bufflen) {
+ − 183
if (*source == '=') {
+ − 184
strncpy(out, source+1, bufflen); /* remove first char */
+ − 185
out[bufflen-1] = '\0'; /* ensures null termination */
+ − 186
}
+ − 187
else { /* out = "source", or "...source" */
+ − 188
if (*source == '@') {
+ − 189
size_t l;
+ − 190
source++; /* skip the `@' */
+ − 191
bufflen -= sizeof(" '...' ");
+ − 192
l = strlen(source);
+ − 193
strcpy(out, "");
+ − 194
if (l > bufflen) {
+ − 195
source += (l-bufflen); /* get last part of file name */
+ − 196
strcat(out, "...");
+ − 197
}
+ − 198
strcat(out, source);
+ − 199
}
+ − 200
else { /* out = [string "string"] */
+ − 201
size_t len = strcspn(source, "\n\r"); /* stop at first newline */
+ − 202
bufflen -= sizeof(" [string \"...\"] ");
+ − 203
if (len > bufflen) len = bufflen;
+ − 204
strcpy(out, "[string \"");
+ − 205
if (source[len] != '\0') { /* must truncate? */
+ − 206
strncat(out, source, len);
+ − 207
strcat(out, "...");
+ − 208
}
+ − 209
else
+ − 210
strcat(out, source);
+ − 211
strcat(out, "\"]");
+ − 212
}
+ − 213
}
+ − 214
}