lobject.c (24000B)
1 /* 2 ** $Id: lobject.c $ 3 ** Some generic functions over Lua objects 4 ** See Copyright Notice in lua.h 5 */ 6 7 #define lobject_c 8 #define LUA_CORE 9 10 #include "lprefix.h" 11 12 13 #include <float.h> 14 #include <locale.h> 15 #include <math.h> 16 #include <stdarg.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 21 #include "lua.h" 22 23 #include "lctype.h" 24 #include "ldebug.h" 25 #include "ldo.h" 26 #include "lmem.h" 27 #include "lobject.h" 28 #include "lstate.h" 29 #include "lstring.h" 30 #include "lvm.h" 31 32 33 /* 34 ** Computes ceil(log2(x)) 35 */ 36 lu_byte luaO_ceillog2 (unsigned int x) { 37 static const lu_byte log_2[256] = { /* log_2[i - 1] = ceil(log2(i)) */ 38 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, 39 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, 40 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, 41 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, 42 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, 43 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, 44 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, 45 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 46 }; 47 int l = 0; 48 x--; 49 while (x >= 256) { l += 8; x >>= 8; } 50 return cast_byte(l + log_2[x]); 51 } 52 53 /* 54 ** Encodes 'p'% as a floating-point byte, represented as (eeeexxxx). 55 ** The exponent is represented using excess-7. Mimicking IEEE 754, the 56 ** representation normalizes the number when possible, assuming an extra 57 ** 1 before the mantissa (xxxx) and adding one to the exponent (eeee) 58 ** to signal that. So, the real value is (1xxxx) * 2^(eeee - 7 - 1) if 59 ** eeee != 0, and (xxxx) * 2^-7 otherwise (subnormal numbers). 60 */ 61 lu_byte luaO_codeparam (unsigned int p) { 62 if (p >= (cast(lu_mem, 0x1F) << (0xF - 7 - 1)) * 100u) /* overflow? */ 63 return 0xFF; /* return maximum value */ 64 else { 65 p = (cast(l_uint32, p) * 128 + 99) / 100; /* round up the division */ 66 if (p < 0x10) { /* subnormal number? */ 67 /* exponent bits are already zero; nothing else to do */ 68 return cast_byte(p); 69 } 70 else { /* p >= 0x10 implies ceil(log2(p + 1)) >= 5 */ 71 /* preserve 5 bits in 'p' */ 72 unsigned log = luaO_ceillog2(p + 1) - 5u; 73 return cast_byte(((p >> log) - 0x10) | ((log + 1) << 4)); 74 } 75 } 76 } 77 78 79 /* 80 ** Computes 'p' times 'x', where 'p' is a floating-point byte. Roughly, 81 ** we have to multiply 'x' by the mantissa and then shift accordingly to 82 ** the exponent. If the exponent is positive, both the multiplication 83 ** and the shift increase 'x', so we have to care only about overflows. 84 ** For negative exponents, however, multiplying before the shift keeps 85 ** more significant bits, as long as the multiplication does not 86 ** overflow, so we check which order is best. 87 */ 88 l_mem luaO_applyparam (lu_byte p, l_mem x) { 89 unsigned int m = p & 0xF; /* mantissa */ 90 int e = (p >> 4); /* exponent */ 91 if (e > 0) { /* normalized? */ 92 e--; /* correct exponent */ 93 m += 0x10; /* correct mantissa; maximum value is 0x1F */ 94 } 95 e -= 7; /* correct excess-7 */ 96 if (e >= 0) { 97 if (x < (MAX_LMEM / 0x1F) >> e) /* no overflow? */ 98 return (x * m) << e; /* order doesn't matter here */ 99 else /* real overflow */ 100 return MAX_LMEM; 101 } 102 else { /* negative exponent */ 103 e = -e; 104 if (x < MAX_LMEM / 0x1F) /* multiplication cannot overflow? */ 105 return (x * m) >> e; /* multiplying first gives more precision */ 106 else if ((x >> e) < MAX_LMEM / 0x1F) /* cannot overflow after shift? */ 107 return (x >> e) * m; 108 else /* real overflow */ 109 return MAX_LMEM; 110 } 111 } 112 113 114 static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, 115 lua_Integer v2) { 116 switch (op) { 117 case LUA_OPADD: return intop(+, v1, v2); 118 case LUA_OPSUB:return intop(-, v1, v2); 119 case LUA_OPMUL:return intop(*, v1, v2); 120 case LUA_OPMOD: return luaV_mod(L, v1, v2); 121 case LUA_OPIDIV: return luaV_idiv(L, v1, v2); 122 case LUA_OPBAND: return intop(&, v1, v2); 123 case LUA_OPBOR: return intop(|, v1, v2); 124 case LUA_OPBXOR: return intop(^, v1, v2); 125 case LUA_OPSHL: return luaV_shiftl(v1, v2); 126 case LUA_OPSHR: return luaV_shiftr(v1, v2); 127 case LUA_OPUNM: return intop(-, 0, v1); 128 case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1); 129 default: lua_assert(0); return 0; 130 } 131 } 132 133 134 static lua_Number numarith (lua_State *L, int op, lua_Number v1, 135 lua_Number v2) { 136 switch (op) { 137 case LUA_OPADD: return luai_numadd(L, v1, v2); 138 case LUA_OPSUB: return luai_numsub(L, v1, v2); 139 case LUA_OPMUL: return luai_nummul(L, v1, v2); 140 case LUA_OPDIV: return luai_numdiv(L, v1, v2); 141 case LUA_OPPOW: return luai_numpow(L, v1, v2); 142 case LUA_OPIDIV: return luai_numidiv(L, v1, v2); 143 case LUA_OPUNM: return luai_numunm(L, v1); 144 case LUA_OPMOD: return luaV_modf(L, v1, v2); 145 default: lua_assert(0); return 0; 146 } 147 } 148 149 150 int luaO_rawarith (lua_State *L, int op, const TValue *p1, const TValue *p2, 151 TValue *res) { 152 switch (op) { 153 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: 154 case LUA_OPSHL: case LUA_OPSHR: 155 case LUA_OPBNOT: { /* operate only on integers */ 156 lua_Integer i1; lua_Integer i2; 157 if (tointegerns(p1, &i1) && tointegerns(p2, &i2)) { 158 setivalue(res, intarith(L, op, i1, i2)); 159 return 1; 160 } 161 else return 0; /* fail */ 162 } 163 case LUA_OPDIV: case LUA_OPPOW: { /* operate only on floats */ 164 lua_Number n1; lua_Number n2; 165 if (tonumberns(p1, n1) && tonumberns(p2, n2)) { 166 setfltvalue(res, numarith(L, op, n1, n2)); 167 return 1; 168 } 169 else return 0; /* fail */ 170 } 171 default: { /* other operations */ 172 lua_Number n1; lua_Number n2; 173 if (ttisinteger(p1) && ttisinteger(p2)) { 174 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); 175 return 1; 176 } 177 else if (tonumberns(p1, n1) && tonumberns(p2, n2)) { 178 setfltvalue(res, numarith(L, op, n1, n2)); 179 return 1; 180 } 181 else return 0; /* fail */ 182 } 183 } 184 } 185 186 187 void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, 188 StkId res) { 189 if (!luaO_rawarith(L, op, p1, p2, s2v(res))) { 190 /* could not perform raw operation; try metamethod */ 191 luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD)); 192 } 193 } 194 195 196 lu_byte luaO_hexavalue (int c) { 197 lua_assert(lisxdigit(c)); 198 if (lisdigit(c)) return cast_byte(c - '0'); 199 else return cast_byte((ltolower(c) - 'a') + 10); 200 } 201 202 203 static int isneg (const char **s) { 204 if (**s == '-') { (*s)++; return 1; } 205 else if (**s == '+') (*s)++; 206 return 0; 207 } 208 209 210 211 /* 212 ** {================================================================== 213 ** Lua's implementation for 'lua_strx2number' 214 ** =================================================================== 215 */ 216 217 #if !defined(lua_strx2number) 218 219 /* maximum number of significant digits to read (to avoid overflows 220 even with single floats) */ 221 #define MAXSIGDIG 30 222 223 /* 224 ** convert a hexadecimal numeric string to a number, following 225 ** C99 specification for 'strtod' 226 */ 227 static lua_Number lua_strx2number (const char *s, char **endptr) { 228 int dot = lua_getlocaledecpoint(); 229 lua_Number r = l_mathop(0.0); /* result (accumulator) */ 230 int sigdig = 0; /* number of significant digits */ 231 int nosigdig = 0; /* number of non-significant digits */ 232 int e = 0; /* exponent correction */ 233 int neg; /* 1 if number is negative */ 234 int hasdot = 0; /* true after seen a dot */ 235 *endptr = cast_charp(s); /* nothing is valid yet */ 236 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ 237 neg = isneg(&s); /* check sign */ 238 if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ 239 return l_mathop(0.0); /* invalid format (no '0x') */ 240 for (s += 2; ; s++) { /* skip '0x' and read numeral */ 241 if (*s == dot) { 242 if (hasdot) break; /* second dot? stop loop */ 243 else hasdot = 1; 244 } 245 else if (lisxdigit(cast_uchar(*s))) { 246 if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */ 247 nosigdig++; 248 else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */ 249 r = (r * l_mathop(16.0)) + luaO_hexavalue(*s); 250 else e++; /* too many digits; ignore, but still count for exponent */ 251 if (hasdot) e--; /* decimal digit? correct exponent */ 252 } 253 else break; /* neither a dot nor a digit */ 254 } 255 if (nosigdig + sigdig == 0) /* no digits? */ 256 return l_mathop(0.0); /* invalid format */ 257 *endptr = cast_charp(s); /* valid up to here */ 258 e *= 4; /* each digit multiplies/divides value by 2^4 */ 259 if (*s == 'p' || *s == 'P') { /* exponent part? */ 260 int exp1 = 0; /* exponent value */ 261 int neg1; /* exponent sign */ 262 s++; /* skip 'p' */ 263 neg1 = isneg(&s); /* sign */ 264 if (!lisdigit(cast_uchar(*s))) 265 return l_mathop(0.0); /* invalid; must have at least one digit */ 266 while (lisdigit(cast_uchar(*s))) /* read exponent */ 267 exp1 = exp1 * 10 + *(s++) - '0'; 268 if (neg1) exp1 = -exp1; 269 e += exp1; 270 *endptr = cast_charp(s); /* valid up to here */ 271 } 272 if (neg) r = -r; 273 return l_mathop(ldexp)(r, e); 274 } 275 276 #endif 277 /* }====================================================== */ 278 279 280 /* maximum length of a numeral to be converted to a number */ 281 #if !defined (L_MAXLENNUM) 282 #define L_MAXLENNUM 200 283 #endif 284 285 /* 286 ** Convert string 's' to a Lua number (put in 'result'). Return NULL on 287 ** fail or the address of the ending '\0' on success. ('mode' == 'x') 288 ** means a hexadecimal numeral. 289 */ 290 static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { 291 char *endptr; 292 *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */ 293 : lua_str2number(s, &endptr); 294 if (endptr == s) return NULL; /* nothing recognized? */ 295 while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */ 296 return (*endptr == '\0') ? endptr : NULL; /* OK iff no trailing chars */ 297 } 298 299 300 /* 301 ** Convert string 's' to a Lua number (put in 'result') handling the 302 ** current locale. 303 ** This function accepts both the current locale or a dot as the radix 304 ** mark. If the conversion fails, it may mean number has a dot but 305 ** locale accepts something else. In that case, the code copies 's' 306 ** to a buffer (because 's' is read-only), changes the dot to the 307 ** current locale radix mark, and tries to convert again. 308 ** The variable 'mode' checks for special characters in the string: 309 ** - 'n' means 'inf' or 'nan' (which should be rejected) 310 ** - 'x' means a hexadecimal numeral 311 ** - '.' just optimizes the search for the common case (no special chars) 312 */ 313 static const char *l_str2d (const char *s, lua_Number *result) { 314 const char *endptr; 315 const char *pmode = strpbrk(s, ".xXnN"); /* look for special chars */ 316 int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0; 317 if (mode == 'n') /* reject 'inf' and 'nan' */ 318 return NULL; 319 endptr = l_str2dloc(s, result, mode); /* try to convert */ 320 if (endptr == NULL) { /* failed? may be a different locale */ 321 char buff[L_MAXLENNUM + 1]; 322 const char *pdot = strchr(s, '.'); 323 if (pdot == NULL || strlen(s) > L_MAXLENNUM) 324 return NULL; /* string too long or no dot; fail */ 325 strcpy(buff, s); /* copy string to buffer */ 326 buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */ 327 endptr = l_str2dloc(buff, result, mode); /* try again */ 328 if (endptr != NULL) 329 endptr = s + (endptr - buff); /* make relative to 's' */ 330 } 331 return endptr; 332 } 333 334 335 #define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10) 336 #define MAXLASTD cast_int(LUA_MAXINTEGER % 10) 337 338 static const char *l_str2int (const char *s, lua_Integer *result) { 339 lua_Unsigned a = 0; 340 int empty = 1; 341 int neg; 342 while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ 343 neg = isneg(&s); 344 if (s[0] == '0' && 345 (s[1] == 'x' || s[1] == 'X')) { /* hex? */ 346 s += 2; /* skip '0x' */ 347 for (; lisxdigit(cast_uchar(*s)); s++) { 348 a = a * 16 + luaO_hexavalue(*s); 349 empty = 0; 350 } 351 } 352 else { /* decimal */ 353 for (; lisdigit(cast_uchar(*s)); s++) { 354 int d = *s - '0'; 355 if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */ 356 return NULL; /* do not accept it (as integer) */ 357 a = a * 10 + cast_uint(d); 358 empty = 0; 359 } 360 } 361 while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */ 362 if (empty || *s != '\0') return NULL; /* something wrong in the numeral */ 363 else { 364 *result = l_castU2S((neg) ? 0u - a : a); 365 return s; 366 } 367 } 368 369 370 size_t luaO_str2num (const char *s, TValue *o) { 371 lua_Integer i; lua_Number n; 372 const char *e; 373 if ((e = l_str2int(s, &i)) != NULL) { /* try as an integer */ 374 setivalue(o, i); 375 } 376 else if ((e = l_str2d(s, &n)) != NULL) { /* else try as a float */ 377 setfltvalue(o, n); 378 } 379 else 380 return 0; /* conversion failed */ 381 return ct_diff2sz(e - s) + 1; /* success; return string size */ 382 } 383 384 385 int luaO_utf8esc (char *buff, unsigned long x) { 386 int n = 1; /* number of bytes put in buffer (backwards) */ 387 lua_assert(x <= 0x7FFFFFFFu); 388 if (x < 0x80) /* ascii? */ 389 buff[UTF8BUFFSZ - 1] = cast_char(x); 390 else { /* need continuation bytes */ 391 unsigned int mfb = 0x3f; /* maximum that fits in first byte */ 392 do { /* add continuation bytes */ 393 buff[UTF8BUFFSZ - (n++)] = cast_char(0x80 | (x & 0x3f)); 394 x >>= 6; /* remove added bits */ 395 mfb >>= 1; /* now there is one less bit available in first byte */ 396 } while (x > mfb); /* still needs continuation byte? */ 397 buff[UTF8BUFFSZ - n] = cast_char((~mfb << 1) | x); /* add first byte */ 398 } 399 return n; 400 } 401 402 403 /* 404 ** The size of the buffer for the conversion of a number to a string 405 ** 'LUA_N2SBUFFSZ' must be enough to accommodate both LUA_INTEGER_FMT 406 ** and LUA_NUMBER_FMT. For a long long int, this is 19 digits plus a 407 ** sign and a final '\0', adding to 21. For a long double, it can go to 408 ** a sign, the dot, an exponent letter, an exponent sign, 4 exponent 409 ** digits, the final '\0', plus the significant digits, which are 410 ** approximately the *_DIG attribute. 411 */ 412 #if LUA_N2SBUFFSZ < (20 + l_floatatt(DIG)) 413 #error "invalid value for LUA_N2SBUFFSZ" 414 #endif 415 416 417 /* 418 ** Convert a float to a string, adding it to a buffer. First try with 419 ** a not too large number of digits, to avoid noise (for instance, 420 ** 1.1 going to "1.1000000000000001"). If that lose precision, so 421 ** that reading the result back gives a different number, then do the 422 ** conversion again with extra precision. Moreover, if the numeral looks 423 ** like an integer (without a decimal point or an exponent), add ".0" to 424 ** its end. 425 */ 426 static int tostringbuffFloat (lua_Number n, char *buff) { 427 /* first conversion */ 428 int len = l_sprintf(buff, LUA_N2SBUFFSZ, LUA_NUMBER_FMT, 429 (LUAI_UACNUMBER)n); 430 lua_Number check = lua_str2number(buff, NULL); /* read it back */ 431 if (check != n) { /* not enough precision? */ 432 /* convert again with more precision */ 433 len = l_sprintf(buff, LUA_N2SBUFFSZ, LUA_NUMBER_FMT_N, 434 (LUAI_UACNUMBER)n); 435 } 436 /* looks like an integer? */ 437 if (buff[strspn(buff, "-0123456789")] == '\0') { 438 buff[len++] = lua_getlocaledecpoint(); 439 buff[len++] = '0'; /* adds '.0' to result */ 440 } 441 return len; 442 } 443 444 445 /* 446 ** Convert a number object to a string, adding it to a buffer. 447 */ 448 unsigned luaO_tostringbuff (const TValue *obj, char *buff) { 449 int len; 450 lua_assert(ttisnumber(obj)); 451 if (ttisinteger(obj)) 452 len = lua_integer2str(buff, LUA_N2SBUFFSZ, ivalue(obj)); 453 else 454 len = tostringbuffFloat(fltvalue(obj), buff); 455 lua_assert(len < LUA_N2SBUFFSZ); 456 return cast_uint(len); 457 } 458 459 460 /* 461 ** Convert a number object to a Lua string, replacing the value at 'obj' 462 */ 463 void luaO_tostring (lua_State *L, TValue *obj) { 464 char buff[LUA_N2SBUFFSZ]; 465 unsigned len = luaO_tostringbuff(obj, buff); 466 setsvalue(L, obj, luaS_newlstr(L, buff, len)); 467 } 468 469 470 471 472 /* 473 ** {================================================================== 474 ** 'luaO_pushvfstring' 475 ** =================================================================== 476 */ 477 478 /* 479 ** Size for buffer space used by 'luaO_pushvfstring'. It should be 480 ** (LUA_IDSIZE + LUA_N2SBUFFSZ) + a minimal space for basic messages, 481 ** so that 'luaG_addinfo' can work directly on the static buffer. 482 */ 483 #define BUFVFS cast_uint(LUA_IDSIZE + LUA_N2SBUFFSZ + 95) 484 485 /* 486 ** Buffer used by 'luaO_pushvfstring'. 'err' signals an error while 487 ** building result (memory error [1] or buffer overflow [2]). 488 */ 489 typedef struct BuffFS { 490 lua_State *L; 491 char *b; 492 size_t buffsize; 493 size_t blen; /* length of string in 'buff' */ 494 int err; 495 char space[BUFVFS]; /* initial buffer */ 496 } BuffFS; 497 498 499 static void initbuff (lua_State *L, BuffFS *buff) { 500 buff->L = L; 501 buff->b = buff->space; 502 buff->buffsize = sizeof(buff->space); 503 buff->blen = 0; 504 buff->err = 0; 505 } 506 507 508 /* 509 ** Push final result from 'luaO_pushvfstring'. This function may raise 510 ** errors explicitly or through memory errors, so it must run protected. 511 */ 512 static void pushbuff (lua_State *L, void *ud) { 513 BuffFS *buff = cast(BuffFS*, ud); 514 switch (buff->err) { 515 case 1: /* memory error */ 516 luaD_throw(L, LUA_ERRMEM); 517 break; 518 case 2: /* length overflow: Add "..." at the end of result */ 519 if (buff->buffsize - buff->blen < 3) 520 strcpy(buff->b + buff->blen - 3, "..."); /* 'blen' must be > 3 */ 521 else { /* there is enough space left for the "..." */ 522 strcpy(buff->b + buff->blen, "..."); 523 buff->blen += 3; 524 } 525 /* FALLTHROUGH */ 526 default: { /* no errors, but it can raise one creating the new string */ 527 TString *ts = luaS_newlstr(L, buff->b, buff->blen); 528 setsvalue2s(L, L->top.p, ts); 529 L->top.p++; 530 } 531 } 532 } 533 534 535 static const char *clearbuff (BuffFS *buff) { 536 lua_State *L = buff->L; 537 const char *res; 538 if (luaD_rawrunprotected(L, pushbuff, buff) != LUA_OK) /* errors? */ 539 res = NULL; /* error message is on the top of the stack */ 540 else 541 res = getstr(tsvalue(s2v(L->top.p - 1))); 542 if (buff->b != buff->space) /* using dynamic buffer? */ 543 luaM_freearray(L, buff->b, buff->buffsize); /* free it */ 544 return res; 545 } 546 547 548 static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { 549 size_t left = buff->buffsize - buff->blen; /* space left in the buffer */ 550 if (buff->err) /* do nothing else after an error */ 551 return; 552 if (slen > left) { /* new string doesn't fit into current buffer? */ 553 if (slen > ((MAX_SIZE/2) - buff->blen)) { /* overflow? */ 554 memcpy(buff->b + buff->blen, str, left); /* copy what it can */ 555 buff->blen = buff->buffsize; 556 buff->err = 2; /* doesn't add anything else */ 557 return; 558 } 559 else { 560 size_t newsize = buff->buffsize + slen; /* limited to MAX_SIZE/2 */ 561 char *newb = 562 (buff->b == buff->space) /* still using static space? */ 563 ? luaM_reallocvector(buff->L, NULL, 0, newsize, char) 564 : luaM_reallocvector(buff->L, buff->b, buff->buffsize, newsize, 565 char); 566 if (newb == NULL) { /* allocation error? */ 567 buff->err = 1; /* signal a memory error */ 568 return; 569 } 570 if (buff->b == buff->space) /* new buffer (not reallocated)? */ 571 memcpy(newb, buff->b, buff->blen); /* copy previous content */ 572 buff->b = newb; /* set new (larger) buffer... */ 573 buff->buffsize = newsize; /* ...and its new size */ 574 } 575 } 576 memcpy(buff->b + buff->blen, str, slen); /* copy new content */ 577 buff->blen += slen; 578 } 579 580 581 /* 582 ** Add a numeral to the buffer. 583 */ 584 static void addnum2buff (BuffFS *buff, TValue *num) { 585 char numbuff[LUA_N2SBUFFSZ]; 586 unsigned len = luaO_tostringbuff(num, numbuff); 587 addstr2buff(buff, numbuff, len); 588 } 589 590 591 /* 592 ** this function handles only '%d', '%c', '%f', '%p', '%s', and '%%' 593 conventional formats, plus Lua-specific '%I' and '%U' 594 */ 595 const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 596 BuffFS buff; /* holds last part of the result */ 597 const char *e; /* points to next '%' */ 598 initbuff(L, &buff); 599 while ((e = strchr(fmt, '%')) != NULL) { 600 addstr2buff(&buff, fmt, ct_diff2sz(e - fmt)); /* add 'fmt' up to '%' */ 601 switch (*(e + 1)) { /* conversion specifier */ 602 case 's': { /* zero-terminated string */ 603 const char *s = va_arg(argp, char *); 604 if (s == NULL) s = "(null)"; 605 addstr2buff(&buff, s, strlen(s)); 606 break; 607 } 608 case 'c': { /* an 'int' as a character */ 609 char c = cast_char(va_arg(argp, int)); 610 addstr2buff(&buff, &c, sizeof(char)); 611 break; 612 } 613 case 'd': { /* an 'int' */ 614 TValue num; 615 setivalue(&num, va_arg(argp, int)); 616 addnum2buff(&buff, &num); 617 break; 618 } 619 case 'I': { /* a 'lua_Integer' */ 620 TValue num; 621 setivalue(&num, cast(lua_Integer, va_arg(argp, l_uacInt))); 622 addnum2buff(&buff, &num); 623 break; 624 } 625 case 'f': { /* a 'lua_Number' */ 626 TValue num; 627 setfltvalue(&num, cast_num(va_arg(argp, l_uacNumber))); 628 addnum2buff(&buff, &num); 629 break; 630 } 631 case 'p': { /* a pointer */ 632 char bf[LUA_N2SBUFFSZ]; /* enough space for '%p' */ 633 void *p = va_arg(argp, void *); 634 int len = lua_pointer2str(bf, LUA_N2SBUFFSZ, p); 635 addstr2buff(&buff, bf, cast_uint(len)); 636 break; 637 } 638 case 'U': { /* an 'unsigned long' as a UTF-8 sequence */ 639 char bf[UTF8BUFFSZ]; 640 int len = luaO_utf8esc(bf, va_arg(argp, unsigned long)); 641 addstr2buff(&buff, bf + UTF8BUFFSZ - len, cast_uint(len)); 642 break; 643 } 644 case '%': { 645 addstr2buff(&buff, "%", 1); 646 break; 647 } 648 default: { 649 addstr2buff(&buff, e, 2); /* keep unknown format in the result */ 650 break; 651 } 652 } 653 fmt = e + 2; /* skip '%' and the specifier */ 654 } 655 addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ 656 return clearbuff(&buff); /* empty buffer into a new string */ 657 } 658 659 660 const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { 661 const char *msg; 662 va_list argp; 663 va_start(argp, fmt); 664 msg = luaO_pushvfstring(L, fmt, argp); 665 va_end(argp); 666 if (msg == NULL) /* error? */ 667 luaD_throw(L, LUA_ERRMEM); 668 return msg; 669 } 670 671 /* }================================================================== */ 672 673 674 #define RETS "..." 675 #define PRE "[string \"" 676 #define POS "\"]" 677 678 #define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) 679 680 void luaO_chunkid (char *out, const char *source, size_t srclen) { 681 size_t bufflen = LUA_IDSIZE; /* free space in buffer */ 682 if (*source == '=') { /* 'literal' source */ 683 if (srclen <= bufflen) /* small enough? */ 684 memcpy(out, source + 1, srclen * sizeof(char)); 685 else { /* truncate it */ 686 addstr(out, source + 1, bufflen - 1); 687 *out = '\0'; 688 } 689 } 690 else if (*source == '@') { /* file name */ 691 if (srclen <= bufflen) /* small enough? */ 692 memcpy(out, source + 1, srclen * sizeof(char)); 693 else { /* add '...' before rest of name */ 694 addstr(out, RETS, LL(RETS)); 695 bufflen -= LL(RETS); 696 memcpy(out, source + 1 + srclen - bufflen, bufflen * sizeof(char)); 697 } 698 } 699 else { /* string; format as [string "source"] */ 700 const char *nl = strchr(source, '\n'); /* find first new line (if any) */ 701 addstr(out, PRE, LL(PRE)); /* add prefix */ 702 bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ 703 if (srclen < bufflen && nl == NULL) { /* small one-line source? */ 704 addstr(out, source, srclen); /* keep it */ 705 } 706 else { 707 if (nl != NULL) 708 srclen = ct_diff2sz(nl - source); /* stop at first newline */ 709 if (srclen > bufflen) srclen = bufflen; 710 addstr(out, source, srclen); 711 addstr(out, RETS, LL(RETS)); 712 } 713 memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); 714 } 715 } 716