module BNFC.Backend.Common.StrUtils where

import Data.Char (ord)

-- | Function that, given an input string, renders it either as a char (if
-- it has legth 1) or a string. It should also excape characters correctly.
-- The first returned value is the 'type' of the string: either C for char
-- or S for string. (used in the C printer to choose the right rendering
-- function)
-- e.g.
-- >>> renderCharOrString "a"
-- ('C',"'a'")
-- >>> renderCharOrString "abc"
-- ('S',"\"abc\"")
-- >>> renderCharOrString "'"
-- ('C',"'\\''")
-- >>> renderCharOrString "\"\\'"
-- ('S',"\"\\\"\\\\\\'\"")
renderCharOrString :: String -> (Char, String)
renderCharOrString :: [Char] -> (Char, [Char])
renderCharOrString [Char
c] | Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
255 = (Char
'C', Char -> [Char]
forall a. Show a => a -> [Char]
show Char
c)     -- using show should quote '
renderCharOrString [Char]
s = (Char
'S', [Char]
"\"" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
escapeChars [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\"")

-- | Helper function that escapes characters in strings
-- >>> escapeChars "\\"
-- "\\\\"
-- >>> escapeChars "\""
-- "\\\""
-- >>> escapeChars "'"
-- "\\'"
escapeChars :: String -> String
escapeChars :: [Char] -> [Char]
escapeChars [] = []
escapeChars (Char
'\\':[Char]
xs) = Char
'\\' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Char
'\\' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char] -> [Char]
escapeChars [Char]
xs
escapeChars (Char
'\"':[Char]
xs) = Char
'\\' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Char
'\"' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char] -> [Char]
escapeChars [Char]
xs
escapeChars (Char
'\'':[Char]
xs) = Char
'\\' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: Char
'\'' Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char] -> [Char]
escapeChars [Char]
xs
escapeChars (Char
x:[Char]
xs) = Char
x Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
: [Char] -> [Char]
escapeChars [Char]
xs