[project @ 2000-03-23 17:45:17 by simonpj]
[ghc-hetmet.git] / ghc / compiler / absCSyn / CStrings.lhs
1 This module deals with printing C string literals 
2
3 \begin{code}
4 module CStrings(
5         CLabelString, isCLabelString,
6         cSEP, pp_cSEP,
7
8         stringToC, charToC, pprFSInCStyle,
9         charToEasyHaskell
10   ) where
11
12 #include "HsVersions.h"
13
14 import Char     ( ord, chr, isAlphaNum )
15 import Outputable
16 \end{code}
17
18
19 \begin{code}
20 type CLabelString = FAST_STRING         -- A C label, completely unencoded
21
22 isCLabelString :: CLabelString -> Bool  -- Checks to see if this is a valid C label
23 isCLabelString lbl 
24   = all ok (_UNPK_ lbl)
25   where
26     ok c = isAlphaNum c || c == '_' || c == '.'
27         -- The '.' appears in e.g. "foo.so" in the 
28         -- module part of a ExtName.  Maybe it should be separate
29
30 cSEP    = SLIT("_")     -- official C separator
31 pp_cSEP = char '_'
32 \end{code}
33
34 \begin{code}
35 pprFSInCStyle :: FAST_STRING -> SDoc
36 pprFSInCStyle fs = doubleQuotes (text (stringToC (_UNPK_ fs)))
37
38 stringToC   :: String -> String
39 -- Convert a string to the form required by C in a C literal string
40 -- Tthe hassle is what to do w/ strings like "ESC 0"...
41 stringToC ""  = ""
42 stringToC [c] = charToC c
43 stringToC (c:cs)
44     -- if we have something "octifiable" in "c", we'd better "octify"
45     -- the rest of the string, too.
46   = if (c < ' ' || c > '~')
47     then (charToC c) ++ (concat (map char_to_C cs))
48     else (charToC c) ++ (stringToC cs)
49   where
50     char_to_C c | c == '\n' = "\\n"     -- use C escapes when we can
51                 | c == '\a' = "\\a"
52                 | c == '\b' = "\\b"     -- ToDo: chk some of these...
53                 | c == '\r' = "\\r"
54                 | c == '\t' = "\\t"
55                 | c == '\f' = "\\f"
56                 | c == '\v' = "\\v"
57                 | otherwise = '\\' : (octify (ord c))
58
59 charToC :: Char -> String
60 -- Convert a character to the form reqd in a C character literal
61 charToC c = if (c >= ' ' && c <= '~')   -- non-portable...
62             then case c of
63                   '\'' -> "\\'"
64                   '\\' -> "\\\\"
65                   '"'  -> "\\\""
66                   '\n' -> "\\n"
67                   '\a' -> "\\a"
68                   '\b' -> "\\b"
69                   '\r' -> "\\r"
70                   '\t' -> "\\t"
71                   '\f' -> "\\f"
72                   '\v' -> "\\v"
73                   _    -> [c]
74             else '\\' : (octify (ord c))
75
76 charToEasyHaskell :: Char -> String
77 -- Convert a character to the form reqd in a Haskell character literal
78 charToEasyHaskell c
79   = if (c >= 'a' && c <= 'z')
80     || (c >= 'A' && c <= 'Z')
81     || (c >= '0' && c <= '9')
82     then [c]
83     else case c of
84           _    -> '\\' : show (ord c)
85
86 octify :: Int -> String
87 octify n
88   = if n < 8 then
89         [chr (n + ord '0')]
90     else
91         octify (n `quot` 8) ++ [chr (n `rem` 8 + ord '0')]
92 \end{code}
93