2 ** $Id: lobject.c,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $
3 ** Some generic functions over Lua objects
4 ** See Copyright Notice in lua.h
10 #include <sys/lua/lua.h>
23 LUAI_DDEF
const TValue luaO_nilobject_
= {NILCONSTANT
};
27 ** converts an integer to a "floating point byte", represented as
28 ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
29 ** eeeee != 0 and (xxx) otherwise.
31 int luaO_int2fb (unsigned int x
) {
32 int e
= 0; /* exponent */
38 return ((e
+1) << 3) | (cast_int(x
) - 8);
43 int luaO_fb2int (int x
) {
44 int e
= (x
>> 3) & 0x1f;
46 else return ((x
& 7) + 8) << (e
- 1);
50 int luaO_ceillog2 (unsigned int x
) {
51 static const lu_byte log_2
[256] = {
52 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,
53 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,
54 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,
55 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,
56 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,
57 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,
58 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,
59 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 while (x
>= 256) { l
+= 8; x
>>= 8; }
68 lua_Number
luaO_arith (int op
, lua_Number v1
, lua_Number v2
) {
70 case LUA_OPADD
: return luai_numadd(NULL
, v1
, v2
);
71 case LUA_OPSUB
: return luai_numsub(NULL
, v1
, v2
);
72 case LUA_OPMUL
: return luai_nummul(NULL
, v1
, v2
);
73 case LUA_OPDIV
: return luai_numdiv(NULL
, v1
, v2
);
74 case LUA_OPMOD
: return luai_nummod(NULL
, v1
, v2
);
75 case LUA_OPPOW
: return luai_numpow(NULL
, v1
, v2
);
76 case LUA_OPUNM
: return luai_numunm(NULL
, v1
);
77 default: lua_assert(0); return 0;
82 int luaO_hexavalue (int c
) {
83 if (lisdigit(c
)) return c
- '0';
84 else return ltolower(c
) - 'a' + 10;
88 #if !defined(lua_strx2number)
92 static int isneg (const char **s
) {
93 if (**s
== '-') { (*s
)++; return 1; }
94 else if (**s
== '+') (*s
)++;
99 static lua_Number
readhexa (const char **s
, lua_Number r
, int *count
) {
100 for (; lisxdigit(cast_uchar(**s
)); (*s
)++) { /* read integer part */
101 r
= (r
* cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s
)));
109 ** convert an hexadecimal numeric string to a number, following
110 ** C99 specification for 'strtod'
112 static lua_Number
lua_strx2number (const char *s
, char **endptr
) {
115 int neg
= 0; /* 1 if number is negative */
116 *endptr
= cast(char *, s
); /* nothing is valid yet */
117 while (lisspace(cast_uchar(*s
))) s
++; /* skip initial spaces */
118 neg
= isneg(&s
); /* check signal */
119 if (!(*s
== '0' && (*(s
+ 1) == 'x' || *(s
+ 1) == 'X'))) /* check '0x' */
120 return 0.0; /* invalid format (no '0x') */
121 s
+= 2; /* skip '0x' */
122 r
= readhexa(&s
, r
, &i
); /* read integer part */
125 r
= readhexa(&s
, r
, &e
); /* read fractional part */
127 if (i
== 0 && e
== 0)
128 return 0.0; /* invalid format (no digit) */
129 e
*= -4; /* each fractional digit divides value by 2^-4 */
130 *endptr
= cast(char *, s
); /* valid up to here */
131 if (*s
== 'p' || *s
== 'P') { /* exponent part? */
135 neg1
= isneg(&s
); /* signal */
136 if (!lisdigit(cast_uchar(*s
)))
137 goto ret
; /* must have at least one digit */
138 while (lisdigit(cast_uchar(*s
))) /* read exponent */
139 exp1
= exp1
* 10 + *(s
++) - '0';
140 if (neg1
) exp1
= -exp1
;
143 *endptr
= cast(char *, s
); /* valid up to here */
146 return ((e
>= 0) ? (r
* (1ULL << e
)) : (r
/ (1ULL << -e
)));
152 int luaO_str2d (const char *s
, size_t len
, lua_Number
*result
) {
154 if (strpbrk(s
, "nN")) /* reject 'inf' and 'nan' */
156 else if (strpbrk(s
, "xX")) /* hexa? */
157 *result
= lua_strx2number(s
, &endptr
);
159 *result
= lua_str2number(s
, &endptr
);
160 if (endptr
== s
) return 0; /* nothing recognized */
161 while (lisspace(cast_uchar(*endptr
))) endptr
++;
162 return (endptr
== s
+ len
); /* OK if no trailing characters */
167 static void pushstr (lua_State
*L
, const char *str
, size_t l
) {
168 setsvalue2s(L
, L
->top
++, luaS_newlstr(L
, str
, l
));
172 /* this function handles only `%d', `%c', %f, %p, and `%s' formats */
173 const char *luaO_pushvfstring (lua_State
*L
, const char *fmt
, va_list argp
) {
176 const char *e
= strchr(fmt
, '%');
177 if (e
== NULL
) break;
178 luaD_checkstack(L
, 2); /* fmt + item */
179 pushstr(L
, fmt
, e
- fmt
);
182 const char *s
= va_arg(argp
, char *);
183 if (s
== NULL
) s
= "(null)";
184 pushstr(L
, s
, strlen(s
));
189 buff
= cast(char, va_arg(argp
, int));
190 pushstr(L
, &buff
, 1);
194 setnvalue(L
->top
++, cast_num(va_arg(argp
, int)));
198 setnvalue(L
->top
++, cast_num(va_arg(argp
, l_uacNumber
)));
202 char buff
[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
203 int l
= lcompat_sprintf(buff
, sizeof(buff
), "%p", va_arg(argp
, void *));
213 "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
220 luaD_checkstack(L
, 1);
221 pushstr(L
, fmt
, strlen(fmt
));
222 if (n
> 0) luaV_concat(L
, n
+ 1);
223 return svalue(L
->top
- 1);
227 const char *luaO_pushfstring (lua_State
*L
, const char *fmt
, ...) {
231 msg
= luaO_pushvfstring(L
, fmt
, argp
);
237 /* number of chars of a literal string without the ending \0 */
238 #define LL(x) (sizeof(x)/sizeof(char) - 1)
241 #define PRE "[string \""
244 #define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
246 void luaO_chunkid (char *out
, const char *source
, size_t bufflen
) {
247 size_t l
= strlen(source
);
248 if (*source
== '=') { /* 'literal' source */
249 if (l
<= bufflen
) /* small enough? */
250 memcpy(out
, source
+ 1, l
* sizeof(char));
251 else { /* truncate it */
252 addstr(out
, source
+ 1, bufflen
- 1);
256 else if (*source
== '@') { /* file name */
257 if (l
<= bufflen
) /* small enough? */
258 memcpy(out
, source
+ 1, l
* sizeof(char));
259 else { /* add '...' before rest of name */
260 addstr(out
, RETS
, LL(RETS
));
262 memcpy(out
, source
+ 1 + l
- bufflen
, bufflen
* sizeof(char));
265 else { /* string; format as [string "source"] */
266 const char *nl
= strchr(source
, '\n'); /* find first new line (if any) */
267 addstr(out
, PRE
, LL(PRE
)); /* add prefix */
268 bufflen
-= LL(PRE RETS POS
) + 1; /* save space for prefix+suffix+'\0' */
269 if (l
< bufflen
&& nl
== NULL
) { /* small one-line source? */
270 addstr(out
, source
, l
); /* keep it */
273 if (nl
!= NULL
) l
= nl
- source
; /* stop at first newline */
274 if (l
> bufflen
) l
= bufflen
;
275 addstr(out
, source
, l
);
276 addstr(out
, RETS
, LL(RETS
));
278 memcpy(out
, POS
, (LL(POS
) + 1) * sizeof(char));