diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-12-08 13:50:54 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-12-08 13:50:54 -0200 |
commit | ea6b1b42c7f13b15c05c9e2ddd47c3dcd4e600f9 (patch) | |
tree | de83496b8935971b96df9b776277fbb5d132b63f | |
parent | 87024e257dbbe704bfedf27b1f5d144688ddc9d2 (diff) | |
download | lua-ea6b1b42c7f13b15c05c9e2ddd47c3dcd4e600f9.tar.gz lua-ea6b1b42c7f13b15c05c9e2ddd47c3dcd4e600f9.tar.bz2 lua-ea6b1b42c7f13b15c05c9e2ddd47c3dcd4e600f9.zip |
more robust way to test for decimal point separator
-rw-r--r-- | llex.c | 29 |
1 files changed, 20 insertions, 9 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 2.14 2005/12/07 15:32:52 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 2.15 2005/12/07 15:43:05 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -135,8 +135,7 @@ static void inclinenumber (LexState *ls) { | |||
135 | 135 | ||
136 | 136 | ||
137 | void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { | 137 | void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { |
138 | struct lconv *cv = localeconv(); | 138 | ls->decpoint = '.'; |
139 | ls->decpoint = (cv ? cv->decimal_point[0] : '.'); | ||
140 | ls->L = L; | 139 | ls->L = L; |
141 | ls->lookahead.token = TK_EOS; /* no look-ahead token */ | 140 | ls->lookahead.token = TK_EOS; /* no look-ahead token */ |
142 | ls->z = z; | 141 | ls->z = z; |
@@ -166,7 +165,7 @@ static int check_next (LexState *ls, const char *set) { | |||
166 | } | 165 | } |
167 | 166 | ||
168 | 167 | ||
169 | static void correctbuff (LexState *ls, char from, char to) { | 168 | static void buffreplace (LexState *ls, char from, char to) { |
170 | int n = luaZ_bufflen(ls->buff); | 169 | int n = luaZ_bufflen(ls->buff); |
171 | char *p = luaZ_buffer(ls->buff); | 170 | char *p = luaZ_buffer(ls->buff); |
172 | while (n--) | 171 | while (n--) |
@@ -174,6 +173,20 @@ static void correctbuff (LexState *ls, char from, char to) { | |||
174 | } | 173 | } |
175 | 174 | ||
176 | 175 | ||
176 | static void trydecpoint (LexState *ls, SemInfo *seminfo) { | ||
177 | /* format error: try to update decimal point separator */ | ||
178 | struct lconv *cv = localeconv(); | ||
179 | char old = ls->decpoint; | ||
180 | ls->decpoint = (cv ? cv->decimal_point[0] : '.'); | ||
181 | buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ | ||
182 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { | ||
183 | /* format error with correct decimal point: no more options */ | ||
184 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ | ||
185 | luaX_lexerror(ls, "malformed number", TK_NUMBER); | ||
186 | } | ||
187 | } | ||
188 | |||
189 | |||
177 | /* LUA_NUMBER */ | 190 | /* LUA_NUMBER */ |
178 | static void read_numeral (LexState *ls, SemInfo *seminfo) { | 191 | static void read_numeral (LexState *ls, SemInfo *seminfo) { |
179 | lua_assert(isdigit(ls->current)); | 192 | lua_assert(isdigit(ls->current)); |
@@ -187,11 +200,9 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { | |||
187 | } | 200 | } |
188 | } | 201 | } |
189 | save(ls, '\0'); | 202 | save(ls, '\0'); |
190 | correctbuff(ls, '.', ls->decpoint); /* follow locale for decimal point */ | 203 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ |
191 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { | 204 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ |
192 | correctbuff(ls, ls->decpoint, '.'); /* undo change */ | 205 | trydecpoint(ls, seminfo); /* try to update decimal point separator */ |
193 | luaX_lexerror(ls, "malformed number", TK_NUMBER); | ||
194 | } | ||
195 | } | 206 | } |
196 | 207 | ||
197 | 208 | ||