git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: handle UTF16 surrogate pairs and 32bit values in string literals
commitbd0fbe4fe659839883b1d8ff2141a05ba6cbe34e authorAndy Arvanitis <andyarvanitis@gmail.com> dateMon 16 Nov 2015, 23:11 (11 years ago) parent24fdff2
1 file changed+21−2
src/Language/PureScript/Pretty/Cpp.hs+21−2
src/Language/PureScript/Pretty/Cpp.hs+21−2
@@ -22,9 +22,10 @@ module Language.PureScript.Pretty.Cpp (
2222 prettyPrintCpp,
2323) where
2424
25+import Data.Bits
2526import Data.Char
2627import Data.List
27−import Data.Maybe (fromMaybe)
28+import Data.Maybe (catMaybes, fromMaybe)
2829
2930#if __GLASGOW_HASKELL__ < 710
3031import Control.Applicative
@@ -253,8 +254,20 @@ literals = mkPattern' match
253254 match _ = mzero
254255
255256string :: String -> String
256−string s = '"' : concatMap encodeChar s ++ "\""
257+string s = '"' : concatMap encodeChar (decodeSurrogates s) ++ "\""
257258 where
259+ decodeSurrogates :: String -> String
260+ decodeSurrogates [c] = [c]
261+ decodeSurrogates s = catMaybes $ zipWith decodePair s (tail s ++ ['\0'])
262+ where
263+ decodePair :: Char -> Char -> Maybe Char
264+ decodePair a b
265+ | fromEnum a >= 0xD800 && fromEnum a <= 0xDFFF &&
266+ fromEnum b >= 0xD800 && fromEnum b <= 0xDFFF
267+ = Just . chr $ 0x10000 + shiftL (fromEnum a .&. 0x03FF) 10 + (fromEnum b .&. 0x03FF)
268+ decodePair a _
269+ | fromEnum a >= 0xD800 && fromEnum a <= 0xDFFF = Nothing
270+ decodePair a _ = Just a
258271 encodeChar :: Char -> String
259272 encodeChar '\b' = "\\b"
260273 encodeChar '\t' = "\\t"
@@ -264,8 +277,14 @@ string s = '"' : concatMap encodeChar s ++ "\""
264277 encodeChar '\r' = "\\r"
265278 encodeChar '"' = "\\\""
266279 encodeChar '\\' = "\\\\"
280+ encodeChar c | fromEnum c > 0xFFFF = "\\U" ++ leading ++ hex
281+ where
282+ hex = showHex (fromEnum c) ""
283+ leading = replicate (8 - length hex) '0'
267284 encodeChar c | fromEnum c > 0xFFF = "\\u" ++ showHex (fromEnum c) ""
268285 encodeChar c | fromEnum c > 0xFF = "\\u0" ++ showHex (fromEnum c) ""
286+ encodeChar c | fromEnum c < 0x10 = "\\x0" ++ showHex (fromEnum c) ""
287+ encodeChar c | fromEnum c > 0x7E || fromEnum c < 0x20 = "\\x" ++ showHex (fromEnum c) ""
269288 encodeChar c = [c]
270289
271290accessor :: Pattern PrinterState Cpp (String, Cpp)