forked from enlightenment/efl
eolian: try replacing '.' with locale specific decimal point
This fixes parsing of floating point number with locales that use a comma as decimal separator, as strtof/strtod follows locale specific conventions. @fix
This commit is contained in:
parent
6f846d89cd
commit
9a01ab5dd7
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -574,6 +575,38 @@ get_type(Eo_Lexer *ls, Eina_Bool is_float)
|
||||||
return NUM_INT;
|
return NUM_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
replace_decpoint(Eo_Lexer *ls, char prevdecp)
|
||||||
|
{
|
||||||
|
if (ls->decpoint == prevdecp) return;
|
||||||
|
char *bufs = eina_strbuf_string_steal(ls->buff);
|
||||||
|
char *p = bufs;
|
||||||
|
while ((p = strchr(p, prevdecp))) *p = ls->decpoint;
|
||||||
|
eina_strbuf_append(ls->buff, bufs);
|
||||||
|
free(bufs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_val_with_decpoint(Eo_Lexer *ls, Eo_Token *tok, int type)
|
||||||
|
{
|
||||||
|
struct lconv *lc = localeconv();
|
||||||
|
char prev = ls->decpoint;
|
||||||
|
ls->decpoint = lc ? lc->decimal_point[0] : '.';
|
||||||
|
if (ls->decpoint == prev)
|
||||||
|
{
|
||||||
|
eo_lexer_lex_error(ls, "malformed number", TOK_NUMBER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
replace_decpoint(ls, prev);
|
||||||
|
char *end = NULL;
|
||||||
|
if (type == NUM_FLOAT)
|
||||||
|
tok->value.f = strtof(eina_strbuf_string_get(ls->buff), &end);
|
||||||
|
else if (type == NUM_DOUBLE)
|
||||||
|
tok->value.d = strtod(eina_strbuf_string_get(ls->buff), &end);
|
||||||
|
if (end && end[0])
|
||||||
|
eo_lexer_lex_error(ls, "malformed number", TOK_NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float)
|
write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float)
|
||||||
{
|
{
|
||||||
|
@ -582,6 +615,7 @@ write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float)
|
||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
if (is_float)
|
if (is_float)
|
||||||
{
|
{
|
||||||
|
replace_decpoint(ls, '.');
|
||||||
if (type == NUM_FLOAT)
|
if (type == NUM_FLOAT)
|
||||||
tok->value.f = strtof(str, &end);
|
tok->value.f = strtof(str, &end);
|
||||||
else if (type == NUM_DOUBLE)
|
else if (type == NUM_DOUBLE)
|
||||||
|
@ -598,7 +632,14 @@ write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float)
|
||||||
tok->value.ull = strtoull(str, &end, 0);
|
tok->value.ull = strtoull(str, &end, 0);
|
||||||
}
|
}
|
||||||
if (end && end[0])
|
if (end && end[0])
|
||||||
eo_lexer_lex_error(ls, "malformed number", TOK_NUMBER);
|
{
|
||||||
|
if (is_float)
|
||||||
|
{
|
||||||
|
write_val_with_decpoint(ls, tok, type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eo_lexer_lex_error(ls, "malformed number", TOK_NUMBER);
|
||||||
|
}
|
||||||
tok->kw = type;
|
tok->kw = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -875,6 +916,7 @@ eo_lexer_set_input(Eo_Lexer *ls, const char *source)
|
||||||
ls->filename = get_filename(ls);
|
ls->filename = get_filename(ls);
|
||||||
ls->line_number = 1;
|
ls->line_number = 1;
|
||||||
ls->icolumn = ls->column = -1;
|
ls->icolumn = ls->column = -1;
|
||||||
|
ls->decpoint = '.';
|
||||||
next_char(ls);
|
next_char(ls);
|
||||||
if (ls->current != 0xEF)
|
if (ls->current != 0xEF)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -161,9 +161,6 @@ typedef struct _Eo_Lexer
|
||||||
/* this is jumped to when an error happens */
|
/* this is jumped to when an error happens */
|
||||||
jmp_buf err_jmp;
|
jmp_buf err_jmp;
|
||||||
|
|
||||||
/* whether we allow lexing expression related tokens */
|
|
||||||
Eina_Bool expr_mode;
|
|
||||||
|
|
||||||
/* saved context info */
|
/* saved context info */
|
||||||
Eina_List *saved_ctxs;
|
Eina_List *saved_ctxs;
|
||||||
|
|
||||||
|
@ -172,6 +169,12 @@ typedef struct _Eo_Lexer
|
||||||
* case of error - and it's nulled when it's written into a more permanent
|
* case of error - and it's nulled when it's written into a more permanent
|
||||||
* position (e.g. as part of another struct, or into nodes */
|
* position (e.g. as part of another struct, or into nodes */
|
||||||
Eo_Lexer_Temps tmp;
|
Eo_Lexer_Temps tmp;
|
||||||
|
|
||||||
|
/* whether we allow lexing expression related tokens */
|
||||||
|
Eina_Bool expr_mode;
|
||||||
|
|
||||||
|
/* decimal point, by default '.' */
|
||||||
|
char decpoint;
|
||||||
} Eo_Lexer;
|
} Eo_Lexer;
|
||||||
|
|
||||||
int eo_lexer_init (void);
|
int eo_lexer_init (void);
|
||||||
|
|
Loading…
Reference in New Issue