[project @ 2000-04-20 15:18:58 by simonmar]
[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, pprStringInCStyle,
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 pprStringInCStyle :: String -> SDoc
42 pprStringInCStyle s = doubleQuotes (text (stringToC s))
43
44 stringToC   :: String -> String
45 -- Convert a string to the form required by C in a C literal string
46 -- Tthe hassle is what to do w/ strings like "ESC 0"...
47 stringToC ""  = ""
48 stringToC [c] = charToC c
49 stringToC (c:cs)
50     -- if we have something "octifiable" in "c", we'd better "octify"
51     -- the rest of the string, too.
52   = if (c < ' ' || c > '~')
53     then (charToC c) ++ (concat (map char_to_C cs))
54     else (charToC c) ++ (stringToC cs)
55   where
56     char_to_C c | c == '\n' = "\\n"     -- use C escapes when we can
57                 | c == '\a' = "\\a"
58                 | c == '\b' = "\\b"     -- ToDo: chk some of these...
59                 | c == '\r' = "\\r"
60                 | c == '\t' = "\\t"
61                 | c == '\f' = "\\f"
62                 | c == '\v' = "\\v"
63                 | otherwise = '\\' : (octify (ord c))
64
65 charToC :: Char -> String
66 -- Convert a character to the form reqd in a C character literal
67 charToC c = if (c >= ' ' && c <= '~')   -- non-portable...
68             then case c of
69                   '\'' -> "\\'"
70                   '\\' -> "\\\\"
71                   '"'  -> "\\\""
72                   '\n' -> "\\n"
73                   '\a' -> "\\a"
74                   '\b' -> "\\b"
75                   '\r' -> "\\r"
76                   '\t' -> "\\t"
77                   '\f' -> "\\f"
78                   '\v' -> "\\v"
79                   _    -> [c]
80             else '\\' : (octify (ord c))
81
82 charToEasyHaskell :: Char -> String
83 -- Convert a character to the form reqd in a Haskell character literal
84 charToEasyHaskell c
85   = if (c >= 'a' && c <= 'z')
86     || (c >= 'A' && c <= 'Z')
87     || (c >= '0' && c <= '9')
88     then [c]
89     else case c of
90           _    -> '\\' : show (ord c)
91
92 octify :: Int -> String
93 octify n
94   = if n < 8 then
95         [chr (n + ord '0')]
96     else
97         octify (n `quot` 8) ++ [chr (n `rem` 8 + ord '0')]
98 \end{code}
99