aboutsummaryrefslogtreecommitdiff
path: root/src/lua/lobject.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lua/lobject.c (renamed from src/lua-5.3/lobject.c)309
1 files changed, 185 insertions, 124 deletions
diff --git a/src/lua-5.3/lobject.c b/src/lua/lobject.c
index 355bf58..b4efae4 100644
--- a/src/lua-5.3/lobject.c
+++ b/src/lua/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $ 2** $Id: lobject.c $
3** Some generic functions over Lua objects 3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -29,36 +29,6 @@
29#include "lvm.h" 29#include "lvm.h"
30 30
31 31
32
33LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
34
35
36/*
37** converts an integer to a "floating point byte", represented as
38** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
39** eeeee != 0 and (xxx) otherwise.
40*/
41int luaO_int2fb (unsigned int x) {
42 int e = 0; /* exponent */
43 if (x < 8) return x;
44 while (x >= (8 << 4)) { /* coarse steps */
45 x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
46 e += 4;
47 }
48 while (x >= (8 << 1)) { /* fine steps */
49 x = (x + 1) >> 1; /* x = ceil(x / 2) */
50 e++;
51 }
52 return ((e+1) << 3) | (cast_int(x) - 8);
53}
54
55
56/* converts back */
57int luaO_fb2int (int x) {
58 return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1);
59}
60
61
62/* 32/*
63** Computes ceil(log2(x)) 33** Computes ceil(log2(x))
64*/ 34*/
@@ -87,7 +57,7 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
87 case LUA_OPSUB:return intop(-, v1, v2); 57 case LUA_OPSUB:return intop(-, v1, v2);
88 case LUA_OPMUL:return intop(*, v1, v2); 58 case LUA_OPMUL:return intop(*, v1, v2);
89 case LUA_OPMOD: return luaV_mod(L, v1, v2); 59 case LUA_OPMOD: return luaV_mod(L, v1, v2);
90 case LUA_OPIDIV: return luaV_div(L, v1, v2); 60 case LUA_OPIDIV: return luaV_idiv(L, v1, v2);
91 case LUA_OPBAND: return intop(&, v1, v2); 61 case LUA_OPBAND: return intop(&, v1, v2);
92 case LUA_OPBOR: return intop(|, v1, v2); 62 case LUA_OPBOR: return intop(|, v1, v2);
93 case LUA_OPBXOR: return intop(^, v1, v2); 63 case LUA_OPBXOR: return intop(^, v1, v2);
@@ -110,53 +80,55 @@ static lua_Number numarith (lua_State *L, int op, lua_Number v1,
110 case LUA_OPPOW: return luai_numpow(L, v1, v2); 80 case LUA_OPPOW: return luai_numpow(L, v1, v2);
111 case LUA_OPIDIV: return luai_numidiv(L, v1, v2); 81 case LUA_OPIDIV: return luai_numidiv(L, v1, v2);
112 case LUA_OPUNM: return luai_numunm(L, v1); 82 case LUA_OPUNM: return luai_numunm(L, v1);
113 case LUA_OPMOD: { 83 case LUA_OPMOD: return luaV_modf(L, v1, v2);
114 lua_Number m;
115 luai_nummod(L, v1, v2, m);
116 return m;
117 }
118 default: lua_assert(0); return 0; 84 default: lua_assert(0); return 0;
119 } 85 }
120} 86}
121 87
122 88
123void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, 89int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2,
124 TValue *res) { 90 TValue *res) {
125 switch (op) { 91 switch (op) {
126 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: 92 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
127 case LUA_OPSHL: case LUA_OPSHR: 93 case LUA_OPSHL: case LUA_OPSHR:
128 case LUA_OPBNOT: { /* operate only on integers */ 94 case LUA_OPBNOT: { /* operate only on integers */
129 lua_Integer i1; lua_Integer i2; 95 lua_Integer i1; lua_Integer i2;
130 if (tointeger(p1, &i1) && tointeger(p2, &i2)) { 96 if (tointegerns(p1, &i1) && tointegerns(p2, &i2)) {
131 setivalue(res, intarith(L, op, i1, i2)); 97 setivalue(res, intarith(L, op, i1, i2));
132 return; 98 return 1;
133 } 99 }
134 else break; /* go to the end */ 100 else return 0; /* fail */
135 } 101 }
136 case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ 102 case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */
137 lua_Number n1; lua_Number n2; 103 lua_Number n1; lua_Number n2;
138 if (tonumber(p1, &n1) && tonumber(p2, &n2)) { 104 if (tonumberns(p1, n1) && tonumberns(p2, n2)) {
139 setfltvalue(res, numarith(L, op, n1, n2)); 105 setfltvalue(res, numarith(L, op, n1, n2));
140 return; 106 return 1;
141 } 107 }
142 else break; /* go to the end */ 108 else return 0; /* fail */
143 } 109 }
144 default: { /* other operations */ 110 default: { /* other operations */
145 lua_Number n1; lua_Number n2; 111 lua_Number n1; lua_Number n2;
146 if (ttisinteger(p1) && ttisinteger(p2)) { 112 if (ttisinteger(p1) && ttisinteger(p2)) {
147 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); 113 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
148 return; 114 return 1;
149 } 115 }
150 else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { 116 else if (tonumberns(p1, n1) && tonumberns(p2, n2)) {
151 setfltvalue(res, numarith(L, op, n1, n2)); 117 setfltvalue(res, numarith(L, op, n1, n2));
152 return; 118 return 1;
153 } 119 }
154 else break; /* go to the end */ 120 else return 0; /* fail */
155 } 121 }
156 } 122 }
157 /* could not perform raw operation; try metamethod */ 123}
158 lua_assert(L != NULL); /* should not fail when folding (compile time) */ 124
159 luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD)); 125
126void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
127 StkId res) {
128 if (!luaO_rawarith(L, op, p1, p2, s2v(res))) {
129 /* could not perform raw operation; try metamethod */
130 luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
131 }
160} 132}
161 133
162 134
@@ -187,7 +159,7 @@ static int isneg (const char **s) {
187#define MAXSIGDIG 30 159#define MAXSIGDIG 30
188 160
189/* 161/*
190** convert an hexadecimal numeric string to a number, following 162** convert a hexadecimal numeric string to a number, following
191** C99 specification for 'strtod' 163** C99 specification for 'strtod'
192*/ 164*/
193static lua_Number lua_strx2number (const char *s, char **endptr) { 165static lua_Number lua_strx2number (const char *s, char **endptr) {
@@ -198,9 +170,9 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
198 int e = 0; /* exponent correction */ 170 int e = 0; /* exponent correction */
199 int neg; /* 1 if number is negative */ 171 int neg; /* 1 if number is negative */
200 int hasdot = 0; /* true after seen a dot */ 172 int hasdot = 0; /* true after seen a dot */
201 *endptr = cast(char *, s); /* nothing is valid yet */ 173 *endptr = cast_charp(s); /* nothing is valid yet */
202 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ 174 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
203 neg = isneg(&s); /* check signal */ 175 neg = isneg(&s); /* check sign */
204 if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ 176 if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
205 return 0.0; /* invalid format (no '0x') */ 177 return 0.0; /* invalid format (no '0x') */
206 for (s += 2; ; s++) { /* skip '0x' and read numeral */ 178 for (s += 2; ; s++) { /* skip '0x' and read numeral */
@@ -220,20 +192,20 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
220 } 192 }
221 if (nosigdig + sigdig == 0) /* no digits? */ 193 if (nosigdig + sigdig == 0) /* no digits? */
222 return 0.0; /* invalid format */ 194 return 0.0; /* invalid format */
223 *endptr = cast(char *, s); /* valid up to here */ 195 *endptr = cast_charp(s); /* valid up to here */
224 e *= 4; /* each digit multiplies/divides value by 2^4 */ 196 e *= 4; /* each digit multiplies/divides value by 2^4 */
225 if (*s == 'p' || *s == 'P') { /* exponent part? */ 197 if (*s == 'p' || *s == 'P') { /* exponent part? */
226 int exp1 = 0; /* exponent value */ 198 int exp1 = 0; /* exponent value */
227 int neg1; /* exponent signal */ 199 int neg1; /* exponent sign */
228 s++; /* skip 'p' */ 200 s++; /* skip 'p' */
229 neg1 = isneg(&s); /* signal */ 201 neg1 = isneg(&s); /* sign */
230 if (!lisdigit(cast_uchar(*s))) 202 if (!lisdigit(cast_uchar(*s)))
231 return 0.0; /* invalid; must have at least one digit */ 203 return 0.0; /* invalid; must have at least one digit */
232 while (lisdigit(cast_uchar(*s))) /* read exponent */ 204 while (lisdigit(cast_uchar(*s))) /* read exponent */
233 exp1 = exp1 * 10 + *(s++) - '0'; 205 exp1 = exp1 * 10 + *(s++) - '0';
234 if (neg1) exp1 = -exp1; 206 if (neg1) exp1 = -exp1;
235 e += exp1; 207 e += exp1;
236 *endptr = cast(char *, s); /* valid up to here */ 208 *endptr = cast_charp(s); /* valid up to here */
237 } 209 }
238 if (neg) r = -r; 210 if (neg) r = -r;
239 return l_mathop(ldexp)(r, e); 211 return l_mathop(ldexp)(r, e);
@@ -262,7 +234,7 @@ static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
262** Convert string 's' to a Lua number (put in 'result'). Return NULL 234** Convert string 's' to a Lua number (put in 'result'). Return NULL
263** on fail or the address of the ending '\0' on success. 235** on fail or the address of the ending '\0' on success.
264** 'pmode' points to (and 'mode' contains) special things in the string: 236** 'pmode' points to (and 'mode' contains) special things in the string:
265** - 'x'/'X' means an hexadecimal numeral 237** - 'x'/'X' means a hexadecimal numeral
266** - 'n'/'N' means 'inf' or 'nan' (which should be rejected) 238** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
267** - '.' just optimizes the search for the common case (nothing special) 239** - '.' just optimizes the search for the common case (nothing special)
268** This function accepts both the current locale or a dot as the radix 240** This function accepts both the current locale or a dot as the radix
@@ -345,17 +317,17 @@ size_t luaO_str2num (const char *s, TValue *o) {
345 317
346int luaO_utf8esc (char *buff, unsigned long x) { 318int luaO_utf8esc (char *buff, unsigned long x) {
347 int n = 1; /* number of bytes put in buffer (backwards) */ 319 int n = 1; /* number of bytes put in buffer (backwards) */
348 lua_assert(x <= 0x10FFFF); 320 lua_assert(x <= 0x7FFFFFFFu);
349 if (x < 0x80) /* ascii? */ 321 if (x < 0x80) /* ascii? */
350 buff[UTF8BUFFSZ - 1] = cast(char, x); 322 buff[UTF8BUFFSZ - 1] = cast_char(x);
351 else { /* need continuation bytes */ 323 else { /* need continuation bytes */
352 unsigned int mfb = 0x3f; /* maximum that fits in first byte */ 324 unsigned int mfb = 0x3f; /* maximum that fits in first byte */
353 do { /* add continuation bytes */ 325 do { /* add continuation bytes */
354 buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f)); 326 buff[UTF8BUFFSZ - (n++)] = cast_char(0x80 | (x & 0x3f));
355 x >>= 6; /* remove added bits */ 327 x >>= 6; /* remove added bits */
356 mfb >>= 1; /* now there is one less bit available in first byte */ 328 mfb >>= 1; /* now there is one less bit available in first byte */
357 } while (x > mfb); /* still needs continuation byte? */ 329 } while (x > mfb); /* still needs continuation byte? */
358 buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */ 330 buff[UTF8BUFFSZ - n] = cast_char((~mfb << 1) | x); /* add first byte */
359 } 331 }
360 return n; 332 return n;
361} 333}
@@ -366,88 +338,178 @@ int luaO_utf8esc (char *buff, unsigned long x) {
366 338
367 339
368/* 340/*
369** Convert a number object to a string 341** Convert a number object to a string, adding it to a buffer
370*/ 342*/
371void luaO_tostring (lua_State *L, StkId obj) { 343static int tostringbuff (TValue *obj, char *buff) {
372 char buff[MAXNUMBER2STR]; 344 int len;
373 size_t len;
374 lua_assert(ttisnumber(obj)); 345 lua_assert(ttisnumber(obj));
375 if (ttisinteger(obj)) 346 if (ttisinteger(obj))
376 len = lua_integer2str(buff, sizeof(buff), ivalue(obj)); 347 len = lua_integer2str(buff, MAXNUMBER2STR, ivalue(obj));
377 else { 348 else {
378 len = lua_number2str(buff, sizeof(buff), fltvalue(obj)); 349 len = lua_number2str(buff, MAXNUMBER2STR, fltvalue(obj));
379#if !defined(LUA_COMPAT_FLOATSTRING)
380 if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */ 350 if (buff[strspn(buff, "-0123456789")] == '\0') { /* looks like an int? */
381 buff[len++] = lua_getlocaledecpoint(); 351 buff[len++] = lua_getlocaledecpoint();
382 buff[len++] = '0'; /* adds '.0' to result */ 352 buff[len++] = '0'; /* adds '.0' to result */
383 } 353 }
384#endif
385 } 354 }
386 setsvalue2s(L, obj, luaS_newlstr(L, buff, len)); 355 return len;
387} 356}
388 357
389 358
390static void pushstr (lua_State *L, const char *str, size_t l) { 359/*
360** Convert a number object to a Lua string, replacing the value at 'obj'
361*/
362void luaO_tostring (lua_State *L, TValue *obj) {
363 char buff[MAXNUMBER2STR];
364 int len = tostringbuff(obj, buff);
365 setsvalue(L, obj, luaS_newlstr(L, buff, len));
366}
367
368
369
370
371/*
372** {==================================================================
373** 'luaO_pushvfstring'
374** ===================================================================
375*/
376
377/* size for buffer space used by 'luaO_pushvfstring' */
378#define BUFVFS 400
379
380/* buffer used by 'luaO_pushvfstring' */
381typedef struct BuffFS {
382 lua_State *L;
383 int pushed; /* number of string pieces already on the stack */
384 int blen; /* length of partial string in 'space' */
385 char space[BUFVFS]; /* holds last part of the result */
386} BuffFS;
387
388
389/*
390** Push given string to the stack, as part of the buffer. If the stack
391** is almost full, join all partial strings in the stack into one.
392*/
393static void pushstr (BuffFS *buff, const char *str, size_t l) {
394 lua_State *L = buff->L;
391 setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); 395 setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
392 luaD_inctop(L); 396 L->top++; /* may use one extra slot */
397 buff->pushed++;
398 if (buff->pushed > 1 && L->top + 1 >= L->stack_last) {
399 luaV_concat(L, buff->pushed); /* join all partial results into one */
400 buff->pushed = 1;
401 }
393} 402}
394 403
395 404
396/* 405/*
397** this function handles only '%d', '%c', '%f', '%p', and '%s' 406** empty the buffer space into the stack
407*/
408static void clearbuff (BuffFS *buff) {
409 pushstr(buff, buff->space, buff->blen); /* push buffer contents */
410 buff->blen = 0; /* space now is empty */
411}
412
413
414/*
415** Get a space of size 'sz' in the buffer. If buffer has not enough
416** space, empty it. 'sz' must fit in an empty buffer.
417*/
418static char *getbuff (BuffFS *buff, int sz) {
419 lua_assert(buff->blen <= BUFVFS); lua_assert(sz <= BUFVFS);
420 if (sz > BUFVFS - buff->blen) /* not enough space? */
421 clearbuff(buff);
422 return buff->space + buff->blen;
423}
424
425
426#define addsize(b,sz) ((b)->blen += (sz))
427
428
429/*
430** Add 'str' to the buffer. If string is larger than the buffer space,
431** push the string directly to the stack.
432*/
433static void addstr2buff (BuffFS *buff, const char *str, size_t slen) {
434 if (slen <= BUFVFS) { /* does string fit into buffer? */
435 char *bf = getbuff(buff, cast_int(slen));
436 memcpy(bf, str, slen); /* add string to buffer */
437 addsize(buff, cast_int(slen));
438 }
439 else { /* string larger than buffer */
440 clearbuff(buff); /* string comes after buffer's content */
441 pushstr(buff, str, slen); /* push string */
442 }
443}
444
445
446/*
447** Add a number to the buffer.
448*/
449static void addnum2buff (BuffFS *buff, TValue *num) {
450 char *numbuff = getbuff(buff, MAXNUMBER2STR);
451 int len = tostringbuff(num, numbuff); /* format number into 'numbuff' */
452 addsize(buff, len);
453}
454
455
456/*
457** this function handles only '%d', '%c', '%f', '%p', '%s', and '%%'
398 conventional formats, plus Lua-specific '%I' and '%U' 458 conventional formats, plus Lua-specific '%I' and '%U'
399*/ 459*/
400const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 460const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
401 int n = 0; 461 BuffFS buff; /* holds last part of the result */
402 for (;;) { 462 const char *e; /* points to next '%' */
403 const char *e = strchr(fmt, '%'); 463 buff.pushed = buff.blen = 0;
404 if (e == NULL) break; 464 buff.L = L;
405 pushstr(L, fmt, e - fmt); 465 while ((e = strchr(fmt, '%')) != NULL) {
406 switch (*(e+1)) { 466 addstr2buff(&buff, fmt, e - fmt); /* add 'fmt' up to '%' */
467 switch (*(e + 1)) { /* conversion specifier */
407 case 's': { /* zero-terminated string */ 468 case 's': { /* zero-terminated string */
408 const char *s = va_arg(argp, char *); 469 const char *s = va_arg(argp, char *);
409 if (s == NULL) s = "(null)"; 470 if (s == NULL) s = "(null)";
410 pushstr(L, s, strlen(s)); 471 addstr2buff(&buff, s, strlen(s));
411 break; 472 break;
412 } 473 }
413 case 'c': { /* an 'int' as a character */ 474 case 'c': { /* an 'int' as a character */
414 char buff = cast(char, va_arg(argp, int)); 475 char c = cast_uchar(va_arg(argp, int));
415 if (lisprint(cast_uchar(buff))) 476 addstr2buff(&buff, &c, sizeof(char));
416 pushstr(L, &buff, 1);
417 else /* non-printable character; print its code */
418 luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
419 break; 477 break;
420 } 478 }
421 case 'd': { /* an 'int' */ 479 case 'd': { /* an 'int' */
422 setivalue(L->top, va_arg(argp, int)); 480 TValue num;
423 goto top2str; 481 setivalue(&num, va_arg(argp, int));
482 addnum2buff(&buff, &num);
483 break;
424 } 484 }
425 case 'I': { /* a 'lua_Integer' */ 485 case 'I': { /* a 'lua_Integer' */
426 setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt))); 486 TValue num;
427 goto top2str; 487 setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt)));
488 addnum2buff(&buff, &num);
489 break;
428 } 490 }
429 case 'f': { /* a 'lua_Number' */ 491 case 'f': { /* a 'lua_Number' */
430 setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber))); 492 TValue num;
431 top2str: /* convert the top element to a string */ 493 setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber)));
432 luaD_inctop(L); 494 addnum2buff(&buff, &num);
433 luaO_tostring(L, L->top - 1);
434 break; 495 break;
435 } 496 }
436 case 'p': { /* a pointer */ 497 case 'p': { /* a pointer */
437 char buff[4*sizeof(void *) + 8]; /* should be enough space for a '%p' */ 498 const int sz = 3 * sizeof(void*) + 8; /* enough space for '%p' */
499 char *bf = getbuff(&buff, sz);
438 void *p = va_arg(argp, void *); 500 void *p = va_arg(argp, void *);
439 int l = lua_pointer2str(buff, sizeof(buff), p); 501 int len = lua_pointer2str(bf, sz, p);
440 pushstr(L, buff, l); 502 addsize(&buff, len);
441 break; 503 break;
442 } 504 }
443 case 'U': { /* an 'int' as a UTF-8 sequence */ 505 case 'U': { /* a 'long' as a UTF-8 sequence */
444 char buff[UTF8BUFFSZ]; 506 char bf[UTF8BUFFSZ];
445 int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long))); 507 int len = luaO_utf8esc(bf, va_arg(argp, long));
446 pushstr(L, buff + UTF8BUFFSZ - l, l); 508 addstr2buff(&buff, bf + UTF8BUFFSZ - len, len);
447 break; 509 break;
448 } 510 }
449 case '%': { 511 case '%': {
450 pushstr(L, "%", 1); 512 addstr2buff(&buff, "%", 1);
451 break; 513 break;
452 } 514 }
453 default: { 515 default: {
@@ -455,13 +517,13 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
455 *(e + 1)); 517 *(e + 1));
456 } 518 }
457 } 519 }
458 n += 2; 520 fmt = e + 2; /* skip '%' and the specifier */
459 fmt = e+2;
460 } 521 }
461 luaD_checkstack(L, 1); 522 addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
462 pushstr(L, fmt, strlen(fmt)); 523 clearbuff(&buff); /* empty buffer into the stack */
463 if (n > 0) luaV_concat(L, n + 1); 524 if (buff.pushed > 1)
464 return svalue(L->top - 1); 525 luaV_concat(L, buff.pushed); /* join all partial results */
526 return svalue(s2v(L->top - 1));
465} 527}
466 528
467 529
@@ -474,9 +536,8 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
474 return msg; 536 return msg;
475} 537}
476 538
539/* }================================================================== */
477 540
478/* number of chars of a literal string without the ending \0 */
479#define LL(x) (sizeof(x)/sizeof(char) - 1)
480 541
481#define RETS "..." 542#define RETS "..."
482#define PRE "[string \"" 543#define PRE "[string \""
@@ -484,36 +545,36 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
484 545
485#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) 546#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
486 547
487void luaO_chunkid (char *out, const char *source, size_t bufflen) { 548void luaO_chunkid (char *out, const char *source, size_t srclen) {
488 size_t l = strlen(source); 549 size_t bufflen = LUA_IDSIZE; /* free space in buffer */
489 if (*source == '=') { /* 'literal' source */ 550 if (*source == '=') { /* 'literal' source */
490 if (l <= bufflen) /* small enough? */ 551 if (srclen <= bufflen) /* small enough? */
491 memcpy(out, source + 1, l * sizeof(char)); 552 memcpy(out, source + 1, srclen * sizeof(char));
492 else { /* truncate it */ 553 else { /* truncate it */
493 addstr(out, source + 1, bufflen - 1); 554 addstr(out, source + 1, bufflen - 1);
494 *out = '\0'; 555 *out = '\0';
495 } 556 }
496 } 557 }
497 else if (*source == '@') { /* file name */ 558 else if (*source == '@') { /* file name */
498 if (l <= bufflen) /* small enough? */ 559 if (srclen <= bufflen) /* small enough? */
499 memcpy(out, source + 1, l * sizeof(char)); 560 memcpy(out, source + 1, srclen * sizeof(char));
500 else { /* add '...' before rest of name */ 561 else { /* add '...' before rest of name */
501 addstr(out, RETS, LL(RETS)); 562 addstr(out, RETS, LL(RETS));
502 bufflen -= LL(RETS); 563 bufflen -= LL(RETS);
503 memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); 564 memcpy(out, source + 1 + srclen - bufflen, bufflen * sizeof(char));
504 } 565 }
505 } 566 }
506 else { /* string; format as [string "source"] */ 567 else { /* string; format as [string "source"] */
507 const char *nl = strchr(source, '\n'); /* find first new line (if any) */ 568 const char *nl = strchr(source, '\n'); /* find first new line (if any) */
508 addstr(out, PRE, LL(PRE)); /* add prefix */ 569 addstr(out, PRE, LL(PRE)); /* add prefix */
509 bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ 570 bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
510 if (l < bufflen && nl == NULL) { /* small one-line source? */ 571 if (srclen < bufflen && nl == NULL) { /* small one-line source? */
511 addstr(out, source, l); /* keep it */ 572 addstr(out, source, srclen); /* keep it */
512 } 573 }
513 else { 574 else {
514 if (nl != NULL) l = nl - source; /* stop at first newline */ 575 if (nl != NULL) srclen = nl - source; /* stop at first newline */
515 if (l > bufflen) l = bufflen; 576 if (srclen > bufflen) srclen = bufflen;
516 addstr(out, source, l); 577 addstr(out, source, srclen);
517 addstr(out, RETS, LL(RETS)); 578 addstr(out, RETS, LL(RETS));
518 } 579 }
519 memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); 580 memcpy(out, POS, (LL(POS) + 1) * sizeof(char));