diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-10-23 17:16:17 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-10-23 17:16:17 -0300 |
| commit | e3ce88c9e850b7e79751083014699c5eae1bff31 (patch) | |
| tree | e73392a16c560ed532ef2238132f0e58d2eb23b3 /lobject.c | |
| parent | 5ffcd458f001fce02e5f20a6130e145c6a3caf53 (diff) | |
| download | lua-e3ce88c9e850b7e79751083014699c5eae1bff31.tar.gz lua-e3ce88c9e850b7e79751083014699c5eae1bff31.tar.bz2 lua-e3ce88c9e850b7e79751083014699c5eae1bff31.zip | |
New function 'lua_numbertostrbuff'
It converts a Lua number to a string in a buffer, without creating
a new Lua string.
Diffstat (limited to 'lobject.c')
| -rw-r--r-- | lobject.c | 44 |
1 files changed, 23 insertions, 21 deletions
| @@ -400,15 +400,17 @@ int luaO_utf8esc (char *buff, unsigned long x) { | |||
| 400 | 400 | ||
| 401 | 401 | ||
| 402 | /* | 402 | /* |
| 403 | ** Maximum length of the conversion of a number to a string. Must be | 403 | ** The size of the buffer for the conversion of a number to a string |
| 404 | ** enough to accommodate both LUA_INTEGER_FMT and LUA_NUMBER_FMT. | 404 | ** 'LUA_N2SBUFFSZ' must be enough to accommodate both LUA_INTEGER_FMT |
| 405 | ** For a long long int, this is 19 digits plus a sign and a final '\0', | 405 | ** and LUA_NUMBER_FMT. For a long long int, this is 19 digits plus a |
| 406 | ** adding to 21. For a long double, it can go to a sign, the dot, an | 406 | ** sign and a final '\0', adding to 21. For a long double, it can go to |
| 407 | ** exponent letter, an exponent sign, 4 exponent digits, the final | 407 | ** a sign, the dot, an exponent letter, an exponent sign, 4 exponent |
| 408 | ** '\0', plus the significant digits, which are approximately the *_DIG | 408 | ** digits, the final '\0', plus the significant digits, which are |
| 409 | ** attribute. | 409 | ** approximately the *_DIG attribute. |
| 410 | */ | 410 | */ |
| 411 | #define MAXNUMBER2STR (20 + l_floatatt(DIG)) | 411 | #if LUA_N2SBUFFSZ < (20 + l_floatatt(DIG)) |
| 412 | #error "invalid value for LUA_N2SBUFFSZ" | ||
| 413 | #endif | ||
| 412 | 414 | ||
| 413 | 415 | ||
| 414 | /* | 416 | /* |
| @@ -422,12 +424,12 @@ int luaO_utf8esc (char *buff, unsigned long x) { | |||
| 422 | */ | 424 | */ |
| 423 | static int tostringbuffFloat (lua_Number n, char *buff) { | 425 | static int tostringbuffFloat (lua_Number n, char *buff) { |
| 424 | /* first conversion */ | 426 | /* first conversion */ |
| 425 | int len = l_sprintf(buff, MAXNUMBER2STR, LUA_NUMBER_FMT, | 427 | int len = l_sprintf(buff, LUA_N2SBUFFSZ, LUA_NUMBER_FMT, |
| 426 | (LUAI_UACNUMBER)n); | 428 | (LUAI_UACNUMBER)n); |
| 427 | lua_Number check = lua_str2number(buff, NULL); /* read it back */ | 429 | lua_Number check = lua_str2number(buff, NULL); /* read it back */ |
| 428 | if (check != n) { /* not enough precision? */ | 430 | if (check != n) { /* not enough precision? */ |
| 429 | /* convert again with more precision */ | 431 | /* convert again with more precision */ |
| 430 | len = l_sprintf(buff, MAXNUMBER2STR, LUA_NUMBER_FMT_N, | 432 | len = l_sprintf(buff, LUA_N2SBUFFSZ, LUA_NUMBER_FMT_N, |
| 431 | (LUAI_UACNUMBER)n); | 433 | (LUAI_UACNUMBER)n); |
| 432 | } | 434 | } |
| 433 | /* looks like an integer? */ | 435 | /* looks like an integer? */ |
| @@ -442,14 +444,14 @@ static int tostringbuffFloat (lua_Number n, char *buff) { | |||
| 442 | /* | 444 | /* |
| 443 | ** Convert a number object to a string, adding it to a buffer. | 445 | ** Convert a number object to a string, adding it to a buffer. |
| 444 | */ | 446 | */ |
| 445 | static unsigned tostringbuff (TValue *obj, char *buff) { | 447 | unsigned luaO_tostringbuff (const TValue *obj, char *buff) { |
| 446 | int len; | 448 | int len; |
| 447 | lua_assert(ttisnumber(obj)); | 449 | lua_assert(ttisnumber(obj)); |
| 448 | if (ttisinteger(obj)) | 450 | if (ttisinteger(obj)) |
| 449 | len = lua_integer2str(buff, MAXNUMBER2STR, ivalue(obj)); | 451 | len = lua_integer2str(buff, LUA_N2SBUFFSZ, ivalue(obj)); |
| 450 | else | 452 | else |
| 451 | len = tostringbuffFloat(fltvalue(obj), buff); | 453 | len = tostringbuffFloat(fltvalue(obj), buff); |
| 452 | lua_assert(len < MAXNUMBER2STR); | 454 | lua_assert(len < LUA_N2SBUFFSZ); |
| 453 | return cast_uint(len); | 455 | return cast_uint(len); |
| 454 | } | 456 | } |
| 455 | 457 | ||
| @@ -458,8 +460,8 @@ static unsigned tostringbuff (TValue *obj, char *buff) { | |||
| 458 | ** Convert a number object to a Lua string, replacing the value at 'obj' | 460 | ** Convert a number object to a Lua string, replacing the value at 'obj' |
| 459 | */ | 461 | */ |
| 460 | void luaO_tostring (lua_State *L, TValue *obj) { | 462 | void luaO_tostring (lua_State *L, TValue *obj) { |
| 461 | char buff[MAXNUMBER2STR]; | 463 | char buff[LUA_N2SBUFFSZ]; |
| 462 | unsigned len = tostringbuff(obj, buff); | 464 | unsigned len = luaO_tostringbuff(obj, buff); |
| 463 | setsvalue(L, obj, luaS_newlstr(L, buff, len)); | 465 | setsvalue(L, obj, luaS_newlstr(L, buff, len)); |
| 464 | } | 466 | } |
| 465 | 467 | ||
| @@ -474,10 +476,10 @@ void luaO_tostring (lua_State *L, TValue *obj) { | |||
| 474 | 476 | ||
| 475 | /* | 477 | /* |
| 476 | ** Size for buffer space used by 'luaO_pushvfstring'. It should be | 478 | ** Size for buffer space used by 'luaO_pushvfstring'. It should be |
| 477 | ** (LUA_IDSIZE + MAXNUMBER2STR) + a minimal space for basic messages, | 479 | ** (LUA_IDSIZE + LUA_N2SBUFFSZ) + a minimal space for basic messages, |
| 478 | ** so that 'luaG_addinfo' can work directly on the static buffer. | 480 | ** so that 'luaG_addinfo' can work directly on the static buffer. |
| 479 | */ | 481 | */ |
| 480 | #define BUFVFS cast_uint(LUA_IDSIZE + MAXNUMBER2STR + 95) | 482 | #define BUFVFS cast_uint(LUA_IDSIZE + LUA_N2SBUFFSZ + 95) |
| 481 | 483 | ||
| 482 | /* | 484 | /* |
| 483 | ** Buffer used by 'luaO_pushvfstring'. 'err' signals an error while | 485 | ** Buffer used by 'luaO_pushvfstring'. 'err' signals an error while |
| @@ -579,8 +581,8 @@ static void addstr2buff (BuffFS *buff, const char *str, size_t slen) { | |||
| 579 | ** Add a numeral to the buffer. | 581 | ** Add a numeral to the buffer. |
| 580 | */ | 582 | */ |
| 581 | static void addnum2buff (BuffFS *buff, TValue *num) { | 583 | static void addnum2buff (BuffFS *buff, TValue *num) { |
| 582 | char numbuff[MAXNUMBER2STR]; | 584 | char numbuff[LUA_N2SBUFFSZ]; |
| 583 | unsigned len = tostringbuff(num, numbuff); /* format number into 'numbuff' */ | 585 | unsigned len = luaO_tostringbuff(num, numbuff); |
| 584 | addstr2buff(buff, numbuff, len); | 586 | addstr2buff(buff, numbuff, len); |
| 585 | } | 587 | } |
| 586 | 588 | ||
| @@ -626,9 +628,9 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | |||
| 626 | break; | 628 | break; |
| 627 | } | 629 | } |
| 628 | case 'p': { /* a pointer */ | 630 | case 'p': { /* a pointer */ |
| 629 | char bf[MAXNUMBER2STR]; /* enough space for '%p' */ | 631 | char bf[LUA_N2SBUFFSZ]; /* enough space for '%p' */ |
| 630 | void *p = va_arg(argp, void *); | 632 | void *p = va_arg(argp, void *); |
| 631 | int len = lua_pointer2str(bf, MAXNUMBER2STR, p); | 633 | int len = lua_pointer2str(bf, LUA_N2SBUFFSZ, p); |
| 632 | addstr2buff(&buff, bf, cast_uint(len)); | 634 | addstr2buff(&buff, bf, cast_uint(len)); |
| 633 | break; | 635 | break; |
| 634 | } | 636 | } |
