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