diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-06-18 14:08:58 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2011-06-18 14:08:58 -0300 |
commit | cb4950a6d8b7b3b860ef7581ff148e00995bb5ff (patch) | |
tree | 9dbbc2042bd8342e443bef24e1580412110331d4 | |
parent | fdede8541965a58be39178528d31cdb397010b94 (diff) | |
download | lua-cb4950a6d8b7b3b860ef7581ff148e00995bb5ff.tar.gz lua-cb4950a6d8b7b3b860ef7581ff148e00995bb5ff.tar.bz2 lua-cb4950a6d8b7b3b860ef7581ff148e00995bb5ff.zip |
parser must work with C locale, but external locale must be preserved
-rw-r--r-- | ldo.c | 27 |
1 files changed, 23 insertions, 4 deletions
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.94 2011/05/30 16:36:38 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.95 2011/06/02 19:31:40 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
6 | 6 | ||
7 | 7 | ||
8 | #include <locale.h> | ||
8 | #include <setjmp.h> | 9 | #include <setjmp.h> |
9 | #include <stdlib.h> | 10 | #include <stdlib.h> |
10 | #include <string.h> | 11 | #include <string.h> |
@@ -612,8 +613,22 @@ struct SParser { /* data to `f_parser' */ | |||
612 | Mbuffer buff; /* dynamic structure used by the scanner */ | 613 | Mbuffer buff; /* dynamic structure used by the scanner */ |
613 | Dyndata dyd; /* dynamic structures used by the parser */ | 614 | Dyndata dyd; /* dynamic structures used by the parser */ |
614 | const char *name; | 615 | const char *name; |
616 | TString *savedlocale; | ||
615 | }; | 617 | }; |
616 | 618 | ||
619 | |||
620 | /* | ||
621 | ** save current locale and set locale to "C" for calling the parser | ||
622 | */ | ||
623 | static Proto *callparser (lua_State *L, struct SParser *p, int c) { | ||
624 | const char *oldloc = setlocale(LC_ALL, NULL); /* get current locale */ | ||
625 | p->savedlocale = luaS_new(L, oldloc); /* make a copy */ | ||
626 | setsvalue2s(L, L->top - 1, p->savedlocale); /* anchor it */ | ||
627 | setlocale(LC_ALL, "C"); /* standard locale for parsing Lua files */ | ||
628 | return luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); | ||
629 | } | ||
630 | |||
631 | |||
617 | static void f_parser (lua_State *L, void *ud) { | 632 | static void f_parser (lua_State *L, void *ud) { |
618 | int i; | 633 | int i; |
619 | Proto *tf; | 634 | Proto *tf; |
@@ -621,8 +636,7 @@ static void f_parser (lua_State *L, void *ud) { | |||
621 | struct SParser *p = cast(struct SParser *, ud); | 636 | struct SParser *p = cast(struct SParser *, ud); |
622 | int c = zgetc(p->z); /* read first character */ | 637 | int c = zgetc(p->z); /* read first character */ |
623 | tf = (c == LUA_SIGNATURE[0]) | 638 | tf = (c == LUA_SIGNATURE[0]) |
624 | ? luaU_undump(L, p->z, &p->buff, p->name) | 639 | ? luaU_undump(L, p->z, &p->buff, p->name) : callparser(L, p, c); |
625 | : luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); | ||
626 | setptvalue2s(L, L->top, tf); | 640 | setptvalue2s(L, L->top, tf); |
627 | incr_top(L); | 641 | incr_top(L); |
628 | cl = luaF_newLclosure(L, tf); | 642 | cl = luaF_newLclosure(L, tf); |
@@ -635,8 +649,9 @@ static void f_parser (lua_State *L, void *ud) { | |||
635 | int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { | 649 | int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { |
636 | struct SParser p; | 650 | struct SParser p; |
637 | int status; | 651 | int status; |
652 | setnilvalue(L->top++); /* reserve space for anchoring locale */ | ||
638 | L->nny++; /* cannot yield during parsing */ | 653 | L->nny++; /* cannot yield during parsing */ |
639 | p.z = z; p.name = name; | 654 | p.z = z; p.name = name; p.savedlocale = NULL; |
640 | p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; | 655 | p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; |
641 | p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; | 656 | p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; |
642 | p.dyd.label.arr = NULL; p.dyd.label.size = 0; | 657 | p.dyd.label.arr = NULL; p.dyd.label.size = 0; |
@@ -647,6 +662,10 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { | |||
647 | luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); | 662 | luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); |
648 | luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); | 663 | luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); |
649 | L->nny--; | 664 | L->nny--; |
665 | if (p.savedlocale) /* locale was changed? */ | ||
666 | setlocale(LC_ALL, getstr(p.savedlocale)); /* restore old locale */ | ||
667 | setobjs2s(L, L->top - 2, L->top - 1); /* remove reserved space */ | ||
668 | --L->top; | ||
650 | return status; | 669 | return status; |
651 | } | 670 | } |
652 | 671 | ||