00001
00002
00003
00004
00005
00006
00007 #include <stdarg.h>
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011
00012 #define lobject_c
00013 #define LUA_CORE
00014
00015 #include "lua.h"
00016
00017 #include "lctype.h"
00018 #include "ldebug.h"
00019 #include "ldo.h"
00020 #include "lmem.h"
00021 #include "lobject.h"
00022 #include "lstate.h"
00023 #include "lstring.h"
00024 #include "lvm.h"
00025
00026
00027
00028 LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
00029
00030
00031
00032
00033
00034
00035
00036 int luaO_int2fb (unsigned int x) {
00037 int e = 0;
00038 if (x < 8) return x;
00039 while (x >= 0x10) {
00040 x = (x+1) >> 1;
00041 e++;
00042 }
00043 return ((e+1) << 3) | (cast_int(x) - 8);
00044 }
00045
00046
00047
00048 int luaO_fb2int (int x) {
00049 int e = (x >> 3) & 0x1f;
00050 if (e == 0) return x;
00051 else return ((x & 7) + 8) << (e - 1);
00052 }
00053
00054
00055 int luaO_ceillog2 (unsigned int x) {
00056 static const lu_byte log_2[256] = {
00057 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,
00058 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,
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 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 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
00065 };
00066 int l = 0;
00067 x--;
00068 while (x >= 256) { l += 8; x >>= 8; }
00069 return l + log_2[x];
00070 }
00071
00072
00073 lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
00074 switch (op) {
00075 case LUA_OPADD: return luai_numadd(NULL, v1, v2);
00076 case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
00077 case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
00078 case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
00079 case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
00080 case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
00081 case LUA_OPUNM: return luai_numunm(NULL, v1);
00082 default: lua_assert(0); return 0;
00083 }
00084 }
00085
00086
00087 int luaO_hexavalue (int c) {
00088 if (lisdigit(c)) return c - '0';
00089 else return ltolower(c) - 'a' + 10;
00090 }
00091
00092
00093 #if !defined(lua_strx2number)
00094
00095 #include <math.h>
00096
00097
00098 static int isneg (const char **s) {
00099 if (**s == '-') { (*s)++; return 1; }
00100 else if (**s == '+') (*s)++;
00101 return 0;
00102 }
00103
00104
00105 static lua_Number readhexa (const char **s, lua_Number r, int *count) {
00106 for (; lisxdigit(cast_uchar(**s)); (*s)++) {
00107 r = (r * 16.0) + cast_num(luaO_hexavalue(cast_uchar(**s)));
00108 (*count)++;
00109 }
00110 return r;
00111 }
00112
00113
00114
00115
00116
00117
00118 static lua_Number lua_strx2number (const char *s, char **endptr) {
00119 lua_Number r = 0.0;
00120 int e = 0, i = 0;
00121 int neg = 0;
00122 *endptr = cast(char *, s);
00123 while (lisspace(cast_uchar(*s))) s++;
00124 neg = isneg(&s);
00125 if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')))
00126 return 0.0;
00127 s += 2;
00128 r = readhexa(&s, r, &i);
00129 if (*s == '.') {
00130 s++;
00131 r = readhexa(&s, r, &e);
00132 }
00133 if (i == 0 && e == 0)
00134 return 0.0;
00135 e *= -4;
00136 *endptr = cast(char *, s);
00137 if (*s == 'p' || *s == 'P') {
00138 int exp1 = 0;
00139 int neg1;
00140 s++;
00141 neg1 = isneg(&s);
00142 if (!lisdigit(cast_uchar(*s)))
00143 goto ret;
00144 while (lisdigit(cast_uchar(*s)))
00145 exp1 = exp1 * 10 + *(s++) - '0';
00146 if (neg1) exp1 = -exp1;
00147 e += exp1;
00148 }
00149 *endptr = cast(char *, s);
00150 ret:
00151 if (neg) r = -r;
00152 return ldexp(r, e);
00153 }
00154
00155 #endif
00156
00157
00158 int luaO_str2d (const char *s, size_t len, lua_Number *result) {
00159 char *endptr;
00160 if (strpbrk(s, "nN"))
00161 return 0;
00162 else if (strpbrk(s, "xX"))
00163 *result = lua_strx2number(s, &endptr);
00164 else
00165 *result = lua_str2number(s, &endptr);
00166 if (endptr == s) return 0;
00167 while (lisspace(cast_uchar(*endptr))) endptr++;
00168 return (endptr == s + len);
00169 }
00170
00171
00172
00173 static void pushstr (lua_State *L, const char *str, size_t l) {
00174 setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
00175 incr_top(L);
00176 }
00177
00178
00179
00180 const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
00181 int n = 0;
00182 for (;;) {
00183 const char *e = strchr(fmt, '%');
00184 if (e == NULL) break;
00185 setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
00186 incr_top(L);
00187 switch (*(e+1)) {
00188 case 's': {
00189 const char *s = va_arg(argp, char *);
00190 if (s == NULL) s = "(null)";
00191 pushstr(L, s, strlen(s));
00192 break;
00193 }
00194 case 'c': {
00195 char buff;
00196 buff = cast(char, va_arg(argp, int));
00197 pushstr(L, &buff, 1);
00198 break;
00199 }
00200 case 'd': {
00201 setnvalue(L->top, cast_num(va_arg(argp, int)));
00202 incr_top(L);
00203 break;
00204 }
00205 case 'f': {
00206 setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
00207 incr_top(L);
00208 break;
00209 }
00210 case 'p': {
00211 char buff[4*sizeof(void *) + 8];
00212 int l = sprintf(buff, "%p", va_arg(argp, void *));
00213 pushstr(L, buff, l);
00214 break;
00215 }
00216 case '%': {
00217 pushstr(L, "%", 1);
00218 break;
00219 }
00220 default: {
00221 luaG_runerror(L,
00222 "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
00223 *(e + 1));
00224 }
00225 }
00226 n += 2;
00227 fmt = e+2;
00228 }
00229 pushstr(L, fmt, strlen(fmt));
00230 if (n > 0) luaV_concat(L, n + 1);
00231 return svalue(L->top - 1);
00232 }
00233
00234
00235 const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
00236 const char *msg;
00237 va_list argp;
00238 va_start(argp, fmt);
00239 msg = luaO_pushvfstring(L, fmt, argp);
00240 va_end(argp);
00241 return msg;
00242 }
00243
00244
00245
00246 #define LL(x) (sizeof(x)/sizeof(char) - 1)
00247
00248 #define RETS "..."
00249 #define PRE "[string \""
00250 #define POS "\"]"
00251
00252 #define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
00253
00254 void luaO_chunkid (char *out, const char *source, size_t bufflen) {
00255 size_t l = strlen(source);
00256 if (*source == '=') {
00257 if (l <= bufflen)
00258 memcpy(out, source + 1, l * sizeof(char));
00259 else {
00260 addstr(out, source + 1, bufflen - 1);
00261 *out = '\0';
00262 }
00263 }
00264 else if (*source == '@') {
00265 if (l <= bufflen)
00266 memcpy(out, source + 1, l * sizeof(char));
00267 else {
00268 addstr(out, RETS, LL(RETS));
00269 bufflen -= LL(RETS);
00270 memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
00271 }
00272 }
00273 else {
00274 const char *nl = strchr(source, '\n');
00275 addstr(out, PRE, LL(PRE));
00276 bufflen -= LL(PRE RETS POS) + 1;
00277 if (l < bufflen && nl == NULL) {
00278 addstr(out, source, l);
00279 }
00280 else {
00281 if (nl != NULL) l = nl - source;
00282 if (l > bufflen) l = bufflen;
00283 addstr(out, source, l);
00284 addstr(out, RETS, LL(RETS));
00285 }
00286 memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
00287 }
00288 }
00289