From 911860671d3f35a52b54869a7a3e7730d7c631dd Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 27 Feb 2009 18:00:29 +0000 Subject: [PATCH] z-encode digits at the start of a symbol name; fixes trac #2997 Digits already have a couple of meanings in z-encoding (Z3T is a tuple, and z123U is a unicode character), so we encode digits as unicode characters to avoid trying to squeeze in another meaning. Also removed a little GHC < 6.2 compatibility hack. --- compiler/utils/Encoding.hs | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/compiler/utils/Encoding.hs b/compiler/utils/Encoding.hs index 3381265..35df004 100644 --- a/compiler/utils/Encoding.hs +++ b/compiler/utils/Encoding.hs @@ -29,9 +29,8 @@ module Encoding ( #include "HsVersions.h" import Foreign -import Data.Char ( ord, chr, isDigit, digitToInt, intToDigit, - isHexDigit ) -import Numeric ( showIntAtBase ) +import Data.Char +import Numeric import Data.Bits import GHC.Ptr ( Ptr(..) ) import GHC.Base @@ -239,7 +238,9 @@ zEncodeString cs = case maybe_tuple cs of Nothing -> go cs where go [] = [] - go (c:cs) = encode_ch c ++ go cs + go (c:cs) = encode_digit_ch c ++ go' cs + go' [] = [] + go' (c:cs) = encode_ch c ++ go' cs unencodedChar :: Char -> Bool -- True for chars that don't need encoding unencodedChar 'Z' = False @@ -248,6 +249,12 @@ unencodedChar c = c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' +-- If a digit is at the start of a symbol then we need to encode it. +-- Otherwise package names like 9pH-0.1 give linker errors. +encode_digit_ch :: Char -> EncodedString +encode_digit_ch c | c >= '0' && c <= '9' = encode_as_unicode_char c +encode_digit_ch c | otherwise = encode_ch c + encode_ch :: Char -> EncodedString encode_ch c | unencodedChar c = [c] -- Common case first @@ -279,16 +286,16 @@ encode_ch '/' = "zs" encode_ch '*' = "zt" encode_ch '_' = "zu" encode_ch '%' = "zv" -encode_ch c = 'z' : if isDigit (head hex_str) then hex_str - else '0':hex_str +encode_ch c = encode_as_unicode_char c + +encode_as_unicode_char :: Char -> EncodedString +encode_as_unicode_char c = 'z' : if isDigit (head hex_str) then hex_str + else '0':hex_str where hex_str = showHex (ord c) "U" -- ToDo: we could improve the encoding here in various ways. -- eg. strings of unicode characters come out as 'z1234Uz5678U', we -- could remove the 'U' in the middle (the 'z' works as a separator). - showHex = showIntAtBase 16 intToDigit - -- needed because prior to GHC 6.2, Numeric.showHex added a "0x" prefix - zDecodeString :: EncodedString -> UserString zDecodeString [] = [] zDecodeString ('Z' : d : rest) -- 1.7.10.4