summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2015-06-25 10:43:54 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2015-06-25 10:44:01 +0100
commit9a01ab5dd77830c425440bf497c04e7e88426034 (patch)
treecd5508432e6a125afaef684506da82619c5700b0
parent6f846d89cd3259ff51dc419394a63ccc9cdd83fa (diff)
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
-rw-r--r--src/lib/eolian/eo_lexer.c44
-rw-r--r--src/lib/eolian/eo_lexer.h9
2 files changed, 49 insertions, 4 deletions
diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c
index 5ecdd8758f..d97c9c6676 100644
--- a/src/lib/eolian/eo_lexer.c
+++ b/src/lib/eolian/eo_lexer.c
@@ -4,6 +4,7 @@
4 4
5#include <stdio.h> 5#include <stdio.h>
6#include <ctype.h> 6#include <ctype.h>
7#include <locale.h>
7 8
8#include <setjmp.h> 9#include <setjmp.h>
9#include <assert.h> 10#include <assert.h>
@@ -575,6 +576,38 @@ get_type(Eo_Lexer *ls, Eina_Bool is_float)
575} 576}
576 577
577static void 578static void
579replace_decpoint(Eo_Lexer *ls, char prevdecp)
580{
581 if (ls->decpoint == prevdecp) return;
582 char *bufs = eina_strbuf_string_steal(ls->buff);
583 char *p = bufs;
584 while ((p = strchr(p, prevdecp))) *p = ls->decpoint;
585 eina_strbuf_append(ls->buff, bufs);
586 free(bufs);
587}
588
589static void
590write_val_with_decpoint(Eo_Lexer *ls, Eo_Token *tok, int type)
591{
592 struct lconv *lc = localeconv();
593 char prev = ls->decpoint;
594 ls->decpoint = lc ? lc->decimal_point[0] : '.';
595 if (ls->decpoint == prev)
596 {
597 eo_lexer_lex_error(ls, "malformed number", TOK_NUMBER);
598 return;
599 }
600 replace_decpoint(ls, prev);
601 char *end = NULL;
602 if (type == NUM_FLOAT)
603 tok->value.f = strtof(eina_strbuf_string_get(ls->buff), &end);
604 else if (type == NUM_DOUBLE)
605 tok->value.d = strtod(eina_strbuf_string_get(ls->buff), &end);
606 if (end && end[0])
607 eo_lexer_lex_error(ls, "malformed number", TOK_NUMBER);
608}
609
610static void
578write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float) 611write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float)
579{ 612{
580 const char *str = eina_strbuf_string_get(ls->buff); 613 const char *str = eina_strbuf_string_get(ls->buff);
@@ -582,6 +615,7 @@ write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float)
582 char *end = NULL; 615 char *end = NULL;
583 if (is_float) 616 if (is_float)
584 { 617 {
618 replace_decpoint(ls, '.');
585 if (type == NUM_FLOAT) 619 if (type == NUM_FLOAT)
586 tok->value.f = strtof(str, &end); 620 tok->value.f = strtof(str, &end);
587 else if (type == NUM_DOUBLE) 621 else if (type == NUM_DOUBLE)
@@ -598,7 +632,14 @@ write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float)
598 tok->value.ull = strtoull(str, &end, 0); 632 tok->value.ull = strtoull(str, &end, 0);
599 } 633 }
600 if (end && end[0]) 634 if (end && end[0])
601 eo_lexer_lex_error(ls, "malformed number", TOK_NUMBER); 635 {
636 if (is_float)
637 {
638 write_val_with_decpoint(ls, tok, type);
639 return;
640 }
641 eo_lexer_lex_error(ls, "malformed number", TOK_NUMBER);
642 }
602 tok->kw = type; 643 tok->kw = type;
603} 644}
604 645
@@ -875,6 +916,7 @@ eo_lexer_set_input(Eo_Lexer *ls, const char *source)
875 ls->filename = get_filename(ls); 916 ls->filename = get_filename(ls);
876 ls->line_number = 1; 917 ls->line_number = 1;
877 ls->icolumn = ls->column = -1; 918 ls->icolumn = ls->column = -1;
919 ls->decpoint = '.';
878 next_char(ls); 920 next_char(ls);
879 if (ls->current != 0xEF) 921 if (ls->current != 0xEF)
880 return; 922 return;
diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h
index 713599d1d9..c15b8e25f4 100644
--- a/src/lib/eolian/eo_lexer.h
+++ b/src/lib/eolian/eo_lexer.h
@@ -161,9 +161,6 @@ typedef struct _Eo_Lexer
161 /* this is jumped to when an error happens */ 161 /* this is jumped to when an error happens */
162 jmp_buf err_jmp; 162 jmp_buf err_jmp;
163 163
164 /* whether we allow lexing expression related tokens */
165 Eina_Bool expr_mode;
166
167 /* saved context info */ 164 /* saved context info */
168 Eina_List *saved_ctxs; 165 Eina_List *saved_ctxs;
169 166
@@ -172,6 +169,12 @@ typedef struct _Eo_Lexer
172 * case of error - and it's nulled when it's written into a more permanent 169 * case of error - and it's nulled when it's written into a more permanent
173 * position (e.g. as part of another struct, or into nodes */ 170 * position (e.g. as part of another struct, or into nodes */
174 Eo_Lexer_Temps tmp; 171 Eo_Lexer_Temps tmp;
172
173 /* whether we allow lexing expression related tokens */
174 Eina_Bool expr_mode;
175
176 /* decimal point, by default '.' */
177 char decpoint;
175} Eo_Lexer; 178} Eo_Lexer;
176 179
177int eo_lexer_init (void); 180int eo_lexer_init (void);