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 | } |