0 | module Parser.Support.Escaping
2 | import Libraries.Data.String.Extra
6 | hex : Char -> Maybe Int
26 | dec : Char -> Maybe Int
40 | oct : Char -> Maybe Int
52 | getEsc : String -> Maybe Char
53 | getEsc "NUL" = Just '\NUL'
54 | getEsc "SOH" = Just '\SOH'
55 | getEsc "STX" = Just '\STX'
56 | getEsc "ETX" = Just '\ETX'
57 | getEsc "EOT" = Just '\EOT'
58 | getEsc "ENQ" = Just '\ENQ'
59 | getEsc "ACK" = Just '\ACK'
60 | getEsc "BEL" = Just '\BEL'
61 | getEsc "BS" = Just '\BS'
62 | getEsc "HT" = Just '\HT'
63 | getEsc "LF" = Just '\LF'
64 | getEsc "VT" = Just '\VT'
65 | getEsc "FF" = Just '\FF'
66 | getEsc "CR" = Just '\CR'
67 | getEsc "SO" = Just '\SO'
68 | getEsc "SI" = Just '\SI'
69 | getEsc "DLE" = Just '\DLE'
70 | getEsc "DC1" = Just '\DC1'
71 | getEsc "DC2" = Just '\DC2'
72 | getEsc "DC3" = Just '\DC3'
73 | getEsc "DC4" = Just '\DC4'
74 | getEsc "NAK" = Just '\NAK'
75 | getEsc "SYN" = Just '\SYN'
76 | getEsc "ETB" = Just '\ETB'
77 | getEsc "CAN" = Just '\CAN'
78 | getEsc "EM" = Just '\EM'
79 | getEsc "SUB" = Just '\SUB'
80 | getEsc "ESC" = Just '\ESC'
81 | getEsc "FS" = Just '\FS'
82 | getEsc "GS" = Just '\GS'
83 | getEsc "RS" = Just '\RS'
84 | getEsc "US" = Just '\US'
85 | getEsc "SP" = Just '\SP'
86 | getEsc "DEL" = Just '\DEL'
87 | getEsc str = Nothing
89 | unescape' : List Char -> List Char -> Maybe (List Char)
90 | unescape' _ [] = pure []
91 | unescape' escapeChars (x::xs)
92 | = assert_total $
if escapeChars `isPrefixOf` (x::xs)
93 | then case drop (length escapeChars) (x::xs) of
94 | ('\\' :: xs) => pure $
'\\' :: !(unescape' escapeChars xs)
95 | ('\n' :: xs) => pure !(unescape' escapeChars xs)
96 | ('&' :: xs) => pure !(unescape' escapeChars xs)
97 | ('a' :: xs) => pure $
'\a' :: !(unescape' escapeChars xs)
98 | ('b' :: xs) => pure $
'\b' :: !(unescape' escapeChars xs)
99 | ('f' :: xs) => pure $
'\f' :: !(unescape' escapeChars xs)
100 | ('n' :: xs) => pure $
'\n' :: !(unescape' escapeChars xs)
101 | ('r' :: xs) => pure $
'\r' :: !(unescape' escapeChars xs)
102 | ('t' :: xs) => pure $
'\t' :: !(unescape' escapeChars xs)
103 | ('v' :: xs) => pure $
'\v' :: !(unescape' escapeChars xs)
104 | ('\'' :: xs) => pure $
'\'' :: !(unescape' escapeChars xs)
105 | ('"' :: xs) => pure $
'"' :: !(unescape' escapeChars xs)
106 | ('x' :: xs) => case span isHexDigit xs of
107 | ([], rest) => unescape' escapeChars rest
108 | (ds, rest) => pure $
cast !(toHex 1 (reverse ds)) ::
109 | !(unescape' escapeChars rest)
110 | ('o' :: xs) => case span isOctDigit xs of
111 | ([], rest) => unescape' escapeChars rest
112 | (ds, rest) => pure $
cast !(toOct 1 (reverse ds)) ::
113 | !(unescape' escapeChars rest)
114 | xs => case span isDigit xs of
115 | ([], (a :: b :: c :: rest)) =>
116 | case getEsc (fastPack [a, b, c]) of
117 | Just v => Just (v :: !(unescape' escapeChars rest))
118 | Nothing => case getEsc (fastPack [a, b]) of
119 | Just v => Just (v :: !(unescape' escapeChars (c :: rest)))
120 | Nothing => unescape' escapeChars xs
121 | ([], (a :: b :: [])) =>
122 | case getEsc (fastPack [a, b]) of
123 | Just v => Just (v :: [])
124 | Nothing => unescape' escapeChars xs
125 | ([], rest) => unescape' escapeChars rest
126 | (ds, rest) => Just $
cast (cast {to=Int} (fastPack ds)) ::
127 | !(unescape' escapeChars rest)
128 | else Just $
x :: !(unescape' escapeChars xs)
130 | toHex : Int -> List Char -> Maybe Int
131 | toHex _ [] = Just 0
133 | = pure $
!(hex (toLower d)) * m + !(toHex (m*16) ds)
135 | toOct : Int -> List Char -> Maybe Int
136 | toOct _ [] = Just 0
138 | = pure $
!(oct (toLower d)) * m + !(toOct (m*8) ds)
141 | unescape : Nat -> String -> Maybe String
142 | unescape hashtag x = let escapeChars = '\\' :: replicate hashtag '#' in
143 | fastPack <$> (unescape' escapeChars (unpack x))