aboutsummaryrefslogtreecommitdiff
path: root/lstrlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-02-04 10:52:57 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-02-04 10:52:57 -0200
commit8efcd411fee4e7103cff7b027fca38290cdaa6f7 (patch)
tree3d65016ec6316bed51653e128d540168019a54d7 /lstrlib.c
parent90d016980f47fb4f760be2356e715f92af9a7af8 (diff)
downloadlua-8efcd411fee4e7103cff7b027fca38290cdaa6f7.tar.gz
lua-8efcd411fee4e7103cff7b027fca38290cdaa6f7.tar.bz2
lua-8efcd411fee4e7103cff7b027fca38290cdaa6f7.zip
own implementation for 'string.format("%a")' for C89 platforms
Diffstat (limited to 'lstrlib.c')
-rw-r--r--lstrlib.c87
1 files changed, 84 insertions, 3 deletions
diff --git a/lstrlib.c b/lstrlib.c
index 78f7c378..12407a23 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstrlib.c,v 1.221 2014/12/11 14:03:07 roberto Exp roberto $ 2** $Id: lstrlib.c,v 1.223 2015/02/04 12:52:57 roberto Exp $
3** Standard library for string operations and pattern-matching 3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -797,6 +797,86 @@ static int str_gsub (lua_State *L) {
797** ======================================================= 797** =======================================================
798*/ 798*/
799 799
800#if !defined(lua_number2strx) /* { */
801
802/*
803** Hexadecimal floating-point formatter
804*/
805
806#include <math.h>
807
808#define SIZELENMOD (sizeof(LUA_NUMBER_FRMLEN)/sizeof(char))
809
810
811/*
812** Number of bits that goes into the first digit. It can be any value
813** between 1 and 4; the following definition tries to align the number
814** to nibble boundaries. The default is 1 bit, that aligns double
815** (1+52-bit mantissa) and quad precision (1+112-bit mantissa). For
816** float (24-bit mantissa) and 80-bit long double (64-bit mantissa), 4
817** does the alignment.
818*/
819#define L_NBFD ((sizeof(lua_Number) == 4 || sizeof(lua_Number) == 12) ? 4 : 1)
820
821
822/*
823** Add integer part of 'x' to buffer and return new 'x'
824*/
825static lua_Number adddigit (char *buff, int n, lua_Number x) {
826 double dd = l_mathop(floor)(x); /* get integer part from 'x' */
827 int d = (int)dd;
828 buff[n] = (d < 10 ? d + '0' : d - 10 + 'a'); /* add to buffer */
829 return x - dd; /* return what is left */
830}
831
832
833static int num2straux (char *buff, lua_Number x) {
834 if (x != x || x == HUGE_VAL || x == -HUGE_VAL) /* inf or NaN? */
835 return sprintf(buff, LUA_NUMBER_FMT, x); /* equal to '%g' */
836 else if (x == 0) { /* can be -0... */
837 sprintf(buff, LUA_NUMBER_FMT, x);
838 strcpy(buff + (buff[0] == '-' ? 1 : 0), "0x0p+0");
839 return strlen(buff);
840 }
841 else {
842 int e;
843 lua_Number m = l_mathop(frexp)(x, &e); /* 'x' fraction and exponent */
844 int n = 0; /* character count */
845 if (m < 0) { /* is number negative? */
846 buff[n++] = '-'; /* add signal */
847 m = -m; /* make it positive */
848 }
849 buff[n++] = '0'; buff[n++] = 'x'; /* add "0x" */
850 m = adddigit(buff, n++, m * (1 << L_NBFD)); /* add first digit */
851 e -= L_NBFD; /* this digit goes before the radix point */
852 if (m > 0) { /* more digits? */
853 buff[n++] = '.'; /* add radix point */
854 do { /* add as many digits as needed */
855 m = adddigit(buff, n++, m * 16);
856 } while (m > 0);
857 }
858 n += sprintf(buff + n, "p%+d", e); /* add exponent */
859 return n;
860 }
861}
862
863
864static int lua_number2strx (lua_State *L, char *buff, const char *fmt,
865 lua_Number x) {
866 int n = num2straux(buff, x);
867 if (fmt[SIZELENMOD] == 'A') {
868 int i;
869 for (i = 0; i < n; i++)
870 buff[i] = toupper(uchar(buff[i]));
871 }
872 else if (fmt[SIZELENMOD] != 'a')
873 luaL_error(L, "modifiers for format '%%a'/'%%A' not implemented");
874 return n;
875}
876
877#endif /* } */
878
879
800/* 880/*
801** Maximum size of each formatted item. This maximum size is produced 881** Maximum size of each formatted item. This maximum size is produced
802** by format('%.99f', minfloat), and is equal to 99 + 2 ('-' and '.') + 882** by format('%.99f', minfloat), and is equal to 99 + 2 ('-' and '.') +
@@ -908,9 +988,10 @@ static int str_format (lua_State *L) {
908 nb = sprintf(buff, form, n); 988 nb = sprintf(buff, form, n);
909 break; 989 break;
910 } 990 }
911#if defined(LUA_USE_AFORMAT)
912 case 'a': case 'A': 991 case 'a': case 'A':
913#endif 992 addlenmod(form, LUA_NUMBER_FRMLEN);
993 nb = lua_number2strx(L, buff, form, luaL_checknumber(L, arg));
994 break;
914 case 'e': case 'E': case 'f': 995 case 'e': case 'E': case 'f':
915 case 'g': case 'G': { 996 case 'g': case 'G': {
916 addlenmod(form, LUA_NUMBER_FRMLEN); 997 addlenmod(form, LUA_NUMBER_FRMLEN);