module GF.Compile.Coding where import GF.Grammar.Grammar import GF.Grammar.Macros import GF.Text.UTF8 import GF.Text.CP1251 import GF.Infra.Modules import GF.Infra.Option import GF.Data.Operations import Data.Char encodeStringsInModule :: SourceModule -> SourceModule encodeStringsInModule = codeSourceModule encodeUTF8 decodeStringsInModule :: SourceModule -> SourceModule decodeStringsInModule mo = case mo of (_,ModMod m) -> case flag optEncoding (flags m) of UTF_8 -> codeSourceModule decodeUTF8 mo CP_1251 -> codeSourceModule decodeCP1251 mo _ -> mo _ -> mo codeSourceModule :: (String -> String) -> SourceModule -> SourceModule codeSourceModule co (id,moi) = case moi of ModMod mo -> (id, ModMod $ replaceJudgements mo (mapTree codj (jments mo))) _ -> (id,moi) where codj (c,info) = (c, case info of ResOper pty pt -> ResOper (mapP codt pty) (mapP codt pt) ResOverload es tyts -> ResOverload es [(codt ty,codt t) | (ty,t) <- tyts] CncCat pty pt mpr -> CncCat pty (mapP codt pt) (mapP codt mpr) CncFun mty pt mpr -> CncFun mty (mapP codt pt) (mapP codt mpr) _ -> info ) codt t = case t of K s -> K (co s) T ty cs -> T ty [(codp p,codt v) | (p,v) <- cs] _ -> composSafeOp codt t codp p = case p of --- really: composOpPatt PR rs -> PR [(l,codp p) | (l,p) <- rs] PString s -> PString (co s) PChars s -> PChars (co s) PT x p -> PT x (codp p) PAs x p -> PAs x (codp p) PNeg p -> PNeg (codp p) PRep p -> PRep (codp p) PSeq p q -> PSeq (codp p) (codp q) PAlt p q -> PAlt (codp p) (codp q) _ -> p -- | Run an encoding function on all string literals within the given string. codeStringLiterals :: (String -> String) -> String -> String codeStringLiterals _ [] = [] codeStringLiterals co ('"':cs) = '"' : inStringLiteral cs where inStringLiteral [] = error "codeStringLiterals: unterminated string literal" inStringLiteral ('"':ds) = '"' : codeStringLiterals co ds inStringLiteral ('\\':d:ds) = '\\' : co [d] ++ inStringLiteral ds inStringLiteral (d:ds) = co [d] ++ inStringLiteral ds codeStringLiterals co (c:cs) = c : codeStringLiterals co cs