aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c12
-rw-r--r--lauxlib.c7
-rw-r--r--liolib.c22
-rw-r--r--lobject.c44
-rw-r--r--lobject.h1
-rw-r--r--lua.h4
-rw-r--r--manual/manual.of17
7 files changed, 67 insertions, 40 deletions
diff --git a/lapi.c b/lapi.c
index fffd7d26..631cf44e 100644
--- a/lapi.c
+++ b/lapi.c
@@ -368,6 +368,18 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
368} 368}
369 369
370 370
371LUA_API unsigned (lua_numbertostrbuff) (lua_State *L, int idx, char *buff) {
372 const TValue *o = index2value(L, idx);
373 if (ttisnumber(o)) {
374 unsigned len = luaO_tostringbuff(o, buff);
375 buff[len++] = '\0'; /* add final zero */
376 return len;
377 }
378 else
379 return 0;
380}
381
382
371LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) { 383LUA_API size_t lua_stringtonumber (lua_State *L, const char *s) {
372 size_t sz = luaO_str2num(s, s2v(L->top.p)); 384 size_t sz = luaO_str2num(s, s2v(L->top.p));
373 if (sz != 0) 385 if (sz != 0)
diff --git a/lauxlib.c b/lauxlib.c
index a36655f2..e4b12587 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -920,10 +920,9 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
920 else { 920 else {
921 switch (lua_type(L, idx)) { 921 switch (lua_type(L, idx)) {
922 case LUA_TNUMBER: { 922 case LUA_TNUMBER: {
923 if (lua_isinteger(L, idx)) 923 char buff[LUA_N2SBUFFSZ];
924 lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx)); 924 lua_numbertostrbuff(L, idx, buff);
925 else 925 lua_pushstring(L, buff);
926 lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx));
927 break; 926 break;
928 } 927 }
929 case LUA_TSTRING: 928 case LUA_TSTRING:
diff --git a/liolib.c b/liolib.c
index 17522bb2..98ff3d0d 100644
--- a/liolib.c
+++ b/liolib.c
@@ -665,20 +665,16 @@ static int g_write (lua_State *L, FILE *f, int arg) {
665 int status = 1; 665 int status = 1;
666 errno = 0; 666 errno = 0;
667 for (; nargs--; arg++) { 667 for (; nargs--; arg++) {
668 if (lua_type(L, arg) == LUA_TNUMBER) { 668 char buff[LUA_N2SBUFFSZ];
669 /* optimization: could be done exactly as for strings */ 669 const char *s;
670 int len = lua_isinteger(L, arg) 670 size_t len = lua_numbertostrbuff(L, arg, buff); /* try as a number */
671 ? fprintf(f, LUA_INTEGER_FMT, 671 if (len > 0) { /* did conversion work (value was a number)? */
672 (LUAI_UACINT)lua_tointeger(L, arg)) 672 s = buff;
673 : fprintf(f, LUA_NUMBER_FMT, 673 len--;
674 (LUAI_UACNUMBER)lua_tonumber(L, arg));
675 status = status && (len > 0);
676 }
677 else {
678 size_t l;
679 const char *s = luaL_checklstring(L, arg, &l);
680 status = status && (fwrite(s, sizeof(char), l, f) == l);
681 } 674 }
675 else /* must be a string */
676 s = luaL_checklstring(L, arg, &len);
677 status = status && (fwrite(s, sizeof(char), len, f) == len);
682 } 678 }
683 if (l_likely(status)) 679 if (l_likely(status))
684 return 1; /* file handle already on stack top */ 680 return 1; /* file handle already on stack top */
diff --git a/lobject.c b/lobject.c
index ba10189d..97dacaf5 100644
--- a/lobject.c
+++ b/lobject.c
@@ -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*/
423static int tostringbuffFloat (lua_Number n, char *buff) { 425static 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*/
445static unsigned tostringbuff (TValue *obj, char *buff) { 447unsigned 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*/
460void luaO_tostring (lua_State *L, TValue *obj) { 462void 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*/
581static void addnum2buff (BuffFS *buff, TValue *num) { 583static 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 }
diff --git a/lobject.h b/lobject.h
index 2411410b..b1407b77 100644
--- a/lobject.h
+++ b/lobject.h
@@ -845,6 +845,7 @@ LUAI_FUNC int luaO_rawarith (lua_State *L, int op, const TValue *p1,
845LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, 845LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
846 const TValue *p2, StkId res); 846 const TValue *p2, StkId res);
847LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); 847LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o);
848LUAI_FUNC unsigned luaO_tostringbuff (const TValue *obj, char *buff);
848LUAI_FUNC lu_byte luaO_hexavalue (int c); 849LUAI_FUNC lu_byte luaO_hexavalue (int c);
849LUAI_FUNC void luaO_tostring (lua_State *L, TValue *obj); 850LUAI_FUNC void luaO_tostring (lua_State *L, TValue *obj);
850LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, 851LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
diff --git a/lua.h b/lua.h
index dcf49264..5fbc9d34 100644
--- a/lua.h
+++ b/lua.h
@@ -371,7 +371,9 @@ LUA_API int (lua_next) (lua_State *L, int idx);
371LUA_API void (lua_concat) (lua_State *L, int n); 371LUA_API void (lua_concat) (lua_State *L, int n);
372LUA_API void (lua_len) (lua_State *L, int idx); 372LUA_API void (lua_len) (lua_State *L, int idx);
373 373
374LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); 374#define LUA_N2SBUFFSZ 64
375LUA_API unsigned (lua_numbertostrbuff) (lua_State *L, int idx, char *buff);
376LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s);
375 377
376LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); 378LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
377LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); 379LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
diff --git a/manual/manual.of b/manual/manual.of
index 6947b2a0..f0b17b4c 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -675,7 +675,7 @@ approximately @M{n} bytes between steps.
675The garbage-collector step multiplier 675The garbage-collector step multiplier
676controls how much work each incremental step does. 676controls how much work each incremental step does.
677A value of @M{n} means the interpreter will execute 677A value of @M{n} means the interpreter will execute
678@M{n%} @emphx{units of work} for each byte allocated. 678@M{n%} @emphx{units of work} for each word allocated.
679A unit of work corresponds roughly to traversing one slot 679A unit of work corresponds roughly to traversing one slot
680or sweeping one object. 680or sweeping one object.
681Larger values make the collector more aggressive. 681Larger values make the collector more aggressive.
@@ -3829,11 +3829,26 @@ This macro may evaluate its arguments more than once.
3829 3829
3830} 3830}
3831 3831
3832@APIEntry{unsigned (lua_numbertostrbuff) (lua_State *L, int idx,
3833 char *buff);|
3834@apii{0,0,-}
3835
3836Converts the number at acceptable index @id{idx} to a string
3837and puts the result in @id{buff}.
3838The buffer must have a size of at least @Lid{LUA_N2SBUFFSZ} bytes.
3839The conversion follows a non-specified format @see{coercion}.
3840The function returns the number of bytes written to the buffer
3841(including the final zero),
3842or zero if the value at @id{idx} is not a number.
3843
3844}
3845
3832@APIEntry{int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);| 3846@APIEntry{int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);|
3833@apii{nargs + 1,nresults|1,-} 3847@apii{nargs + 1,nresults|1,-}
3834 3848
3835Calls a function (or a callable object) in protected mode. 3849Calls a function (or a callable object) in protected mode.
3836 3850
3851
3837Both @id{nargs} and @id{nresults} have the same meaning as 3852Both @id{nargs} and @id{nresults} have the same meaning as
3838in @Lid{lua_call}. 3853in @Lid{lua_call}.
3839If there are no errors during the call, 3854If there are no errors during the call,