diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-03-21 11:26:44 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2014-03-21 11:26:44 -0300 |
commit | 2d5e2212d4cbf755d509913917f7db36e530385a (patch) | |
tree | 463b8aed3750cd7e145e7fb50ea47081007fd63b | |
parent | da4811238ab48446545621389cb07051982a8279 (diff) | |
download | lua-2d5e2212d4cbf755d509913917f7db36e530385a.tar.gz lua-2d5e2212d4cbf755d509913917f7db36e530385a.tar.bz2 lua-2d5e2212d4cbf755d509913917f7db36e530385a.zip |
native lua_Number may be neither float nor double (in pack/unpackfloat)
-rw-r--r-- | lstrlib.c | 39 |
1 files changed, 22 insertions, 17 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstrlib.c,v 1.187 2014/03/12 18:09:06 roberto Exp roberto $ | 2 | ** $Id: lstrlib.c,v 1.188 2014/03/21 13:52:33 roberto Exp roberto $ |
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 | */ |
@@ -1088,12 +1088,9 @@ static void correctendianess (lua_State *L, char *b, int size, int endianarg) { | |||
1088 | } | 1088 | } |
1089 | 1089 | ||
1090 | 1090 | ||
1091 | #define DEFAULTFLOATSIZE \ | ||
1092 | (sizeof(lua_Number) == sizeof(float) ? "f" : "d") | ||
1093 | |||
1094 | static int getfloatsize (lua_State *L, int arg) { | 1091 | static int getfloatsize (lua_State *L, int arg) { |
1095 | const char *size = luaL_optstring(L, arg, "n"); | 1092 | const char *size = luaL_optstring(L, arg, "n"); |
1096 | if (*size == 'n') size = DEFAULTFLOATSIZE; | 1093 | if (*size == 'n') return sizeof(lua_Number); |
1097 | luaL_argcheck(L, *size == 'd' || *size == 'f', arg, | 1094 | luaL_argcheck(L, *size == 'd' || *size == 'f', arg, |
1098 | "size must be 'f'/'d'/'n'"); | 1095 | "size must be 'f'/'d'/'n'"); |
1099 | return (*size == 'd' ? sizeof(double) : sizeof(float)); | 1096 | return (*size == 'd' ? sizeof(double) : sizeof(float)); |
@@ -1105,13 +1102,16 @@ static int packfloat_l (lua_State *L) { | |||
1105 | char *pn; /* pointer to number */ | 1102 | char *pn; /* pointer to number */ |
1106 | lua_Number n = luaL_checknumber(L, 1); | 1103 | lua_Number n = luaL_checknumber(L, 1); |
1107 | int size = getfloatsize(L, 2); | 1104 | int size = getfloatsize(L, 2); |
1108 | if (size == sizeof(double)) { | 1105 | if (size == sizeof(lua_Number)) |
1109 | d = (double)n; | 1106 | pn = (char*)&n; |
1110 | pn = (char*)&d; | 1107 | else if (size == sizeof(float)) { |
1111 | } | ||
1112 | else { | ||
1113 | f = (float)n; | 1108 | f = (float)n; |
1114 | pn = (char*)&f; | 1109 | pn = (char*)&f; |
1110 | } | ||
1111 | else { /* native lua_Number may be neither float nor double */ | ||
1112 | lua_assert(size == sizeof(double)); | ||
1113 | d = (double)n; | ||
1114 | pn = (char*)&d; | ||
1115 | } | 1115 | } |
1116 | correctendianess(L, pn, size, 3); | 1116 | correctendianess(L, pn, size, 3); |
1117 | lua_pushlstring(L, pn, size); | 1117 | lua_pushlstring(L, pn, size); |
@@ -1127,17 +1127,22 @@ static int unpackfloat_l (lua_State *L) { | |||
1127 | int size = getfloatsize(L, 3); | 1127 | int size = getfloatsize(L, 3); |
1128 | luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1, | 1128 | luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1, |
1129 | "string too short"); | 1129 | "string too short"); |
1130 | if (size == sizeof(double)) { | 1130 | if (size == sizeof(lua_Number)) { |
1131 | double d; | 1131 | memcpy(&res, s + pos - 1, size); |
1132 | memcpy(&d, s + pos - 1, size); | 1132 | correctendianess(L, (char*)&res, size, 4); |
1133 | correctendianess(L, (char*)&d, size, 4); | 1133 | } |
1134 | res = (lua_Number)d; | 1134 | else if (size == sizeof(float)) { |
1135 | } | ||
1136 | else { | ||
1137 | float f; | 1135 | float f; |
1138 | memcpy(&f, s + pos - 1, size); | 1136 | memcpy(&f, s + pos - 1, size); |
1139 | correctendianess(L, (char*)&f, size, 4); | 1137 | correctendianess(L, (char*)&f, size, 4); |
1140 | res = (lua_Number)f; | 1138 | res = (lua_Number)f; |
1139 | } | ||
1140 | else { /* native lua_Number may be neither float nor double */ | ||
1141 | double d; | ||
1142 | lua_assert(size == sizeof(double)); | ||
1143 | memcpy(&d, s + pos - 1, size); | ||
1144 | correctendianess(L, (char*)&d, size, 4); | ||
1145 | res = (lua_Number)d; | ||
1141 | } | 1146 | } |
1142 | lua_pushnumber(L, res); | 1147 | lua_pushnumber(L, res); |
1143 | return 1; | 1148 | return 1; |