q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=9a01ab5dd77830c425440bf497c04e7e88426034

commit 9a01ab5dd77830c425440bf497c04e7e88426034
Author: Daniel Kolesa <d.kol...@osg.samsung.com>
Date:   Thu Jun 25 10:43:54 2015 +0100

    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
---
 src/lib/eolian/eo_lexer.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
 src/lib/eolian/eo_lexer.h |  9 ++++++---
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c
index 5ecdd87..d97c9c6 100644
--- a/src/lib/eolian/eo_lexer.c
+++ b/src/lib/eolian/eo_lexer.c
@@ -4,6 +4,7 @@
 
 #include <stdio.h>
 #include <ctype.h>
+#include <locale.h>
 
 #include <setjmp.h>
 #include <assert.h>
@@ -575,6 +576,38 @@ get_type(Eo_Lexer *ls, Eina_Bool is_float)
 }
 
 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
 write_val(Eo_Lexer *ls, Eo_Token *tok, Eina_Bool is_float)
 {
    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)
    char *end = NULL;
    if (is_float)
      {
+        replace_decpoint(ls, '.');
         if (type == NUM_FLOAT)
           tok->value.f = strtof(str, &end);
         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);
      }
    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;
 }
 
@@ -875,6 +916,7 @@ eo_lexer_set_input(Eo_Lexer *ls, const char *source)
    ls->filename        = get_filename(ls);
    ls->line_number     = 1;
    ls->icolumn         = ls->column = -1;
+   ls->decpoint        = '.';
    next_char(ls);
    if (ls->current != 0xEF)
      return;
diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h
index 713599d..c15b8e2 100644
--- a/src/lib/eolian/eo_lexer.h
+++ b/src/lib/eolian/eo_lexer.h
@@ -161,9 +161,6 @@ typedef struct _Eo_Lexer
    /* this is jumped to when an error happens */
    jmp_buf      err_jmp;
 
-   /* whether we allow lexing expression related tokens */
-   Eina_Bool expr_mode;
-
    /* saved context info */
    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
     * position (e.g. as part of another struct, or into nodes */
    Eo_Lexer_Temps tmp;
+
+   /* whether we allow lexing expression related tokens */
+   Eina_Bool expr_mode;
+
+   /* decimal point, by default '.' */
+   char decpoint;
 } Eo_Lexer;
 
 int         eo_lexer_init           (void);

-- 


Reply via email to