{-# LANGUAGE DeriveDataTypeable #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Language.C.Syntax.Constants
-- Copyright   :  (c) 2007..2008 Duncan Coutts, Benedikt Huber
-- License     :  BSD-style
-- Maintainer  : benedikt.huber@gmail.com
-- Stability   : experimental
-- Portability : ghc
--
-- This module provides support for representing, checking and exporting c
-- constants, i.e. integral, float, character and string constants.
-----------------------------------------------------------------------------
module Language.C.Syntax.Constants (
  -- * Utilities
  escapeChar, unescapeChar, unescapeString,
  Flags(..), noFlags, setFlag, clearFlag, testFlag,
  -- * C char constants (and multi-character character constants)
  cChar, cChar_w, cChars, CChar(..), getCChar, getCCharAsInt, isWideChar, showCharConst,
  -- * C integral constants
  CIntFlag(..), CIntRepr(..), cInteger, CInteger(..), getCInteger,readCInteger,
  -- * C floating point constants
  cFloat,  CFloat(..), readCFloat,
  -- * C string literals
  cString, cString_w, CString(..), getCString, showStringLit, concatCStrings,
  -- * Clang C version literals
  ClangCVersion(..), readClangCVersion,
)
where
import Data.Bits
import Data.Char
import Numeric (showOct, showHex, readHex, readOct, readDec)
import Data.Data (Data)
import GHC.Generics (Generic, Generic1)
import Control.DeepSeq (NFData)

-- | C char constants (abstract)
data CChar = CChar
              !Char
              !Bool  -- wide flag
           | CChars
              [Char] -- multi-character character constant
              !Bool   -- wide flag
           deriving (CChar -> CChar -> Bool
(CChar -> CChar -> Bool) -> (CChar -> CChar -> Bool) -> Eq CChar
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CChar -> CChar -> Bool
== :: CChar -> CChar -> Bool
$c/= :: CChar -> CChar -> Bool
/= :: CChar -> CChar -> Bool
Eq,Eq CChar
Eq CChar =>
(CChar -> CChar -> Ordering)
-> (CChar -> CChar -> Bool)
-> (CChar -> CChar -> Bool)
-> (CChar -> CChar -> Bool)
-> (CChar -> CChar -> Bool)
-> (CChar -> CChar -> CChar)
-> (CChar -> CChar -> CChar)
-> Ord CChar
CChar -> CChar -> Bool
CChar -> CChar -> Ordering
CChar -> CChar -> CChar
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: CChar -> CChar -> Ordering
compare :: CChar -> CChar -> Ordering
$c< :: CChar -> CChar -> Bool
< :: CChar -> CChar -> Bool
$c<= :: CChar -> CChar -> Bool
<= :: CChar -> CChar -> Bool
$c> :: CChar -> CChar -> Bool
> :: CChar -> CChar -> Bool
$c>= :: CChar -> CChar -> Bool
>= :: CChar -> CChar -> Bool
$cmax :: CChar -> CChar -> CChar
max :: CChar -> CChar -> CChar
$cmin :: CChar -> CChar -> CChar
min :: CChar -> CChar -> CChar
Ord,Typeable CChar
Typeable CChar =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> CChar -> c CChar)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c CChar)
-> (CChar -> Constr)
-> (CChar -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c CChar))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CChar))
-> ((forall b. Data b => b -> b) -> CChar -> CChar)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> CChar -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> CChar -> r)
-> (forall u. (forall d. Data d => d -> u) -> CChar -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> CChar -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> CChar -> m CChar)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CChar -> m CChar)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CChar -> m CChar)
-> Data CChar
CChar -> Constr
CChar -> DataType
(forall b. Data b => b -> b) -> CChar -> CChar
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> CChar -> u
forall u. (forall d. Data d => d -> u) -> CChar -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> CChar -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> CChar -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CChar -> m CChar
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CChar -> m CChar
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CChar
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CChar -> c CChar
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CChar)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CChar)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CChar -> c CChar
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CChar -> c CChar
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CChar
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CChar
$ctoConstr :: CChar -> Constr
toConstr :: CChar -> Constr
$cdataTypeOf :: CChar -> DataType
dataTypeOf :: CChar -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CChar)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CChar)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CChar)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c CChar)
$cgmapT :: (forall b. Data b => b -> b) -> CChar -> CChar
gmapT :: (forall b. Data b => b -> b) -> CChar -> CChar
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> CChar -> r
gmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> CChar -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> CChar -> r
gmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> CChar -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> CChar -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> CChar -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CChar -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CChar -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CChar -> m CChar
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CChar -> m CChar
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CChar -> m CChar
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CChar -> m CChar
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CChar -> m CChar
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CChar -> m CChar
Data,(forall x. CChar -> Rep CChar x)
-> (forall x. Rep CChar x -> CChar) -> Generic CChar
forall x. Rep CChar x -> CChar
forall x. CChar -> Rep CChar x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. CChar -> Rep CChar x
from :: forall x. CChar -> Rep CChar x
$cto :: forall x. Rep CChar x -> CChar
to :: forall x. Rep CChar x -> CChar
Generic)

instance Show CChar where
    showsPrec :: Int -> CChar -> ShowS
showsPrec Int
_ (CChar Char
c Bool
wideflag)   = Bool -> ShowS
_showWideFlag Bool
wideflag ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showCharConst Char
c
    showsPrec Int
_ (CChars String
cs Bool
wideflag) = Bool -> ShowS
_showWideFlag Bool
wideflag ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
sQuote ((Char -> String) -> ShowS
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Char -> String
escapeCChar String
cs)

instance NFData CChar

-- | @showCharConst c@ prepends _a_ String representing the C char constant corresponding to @c@.
-- If necessary uses octal or hexadecimal escape sequences.
showCharConst :: Char -> ShowS
showCharConst :: Char -> ShowS
showCharConst Char
c = String -> ShowS
sQuote (String -> ShowS) -> String -> ShowS
forall a b. (a -> b) -> a -> b
$ Char -> String
escapeCChar Char
c

_showWideFlag :: Bool -> ShowS
_showWideFlag :: Bool -> ShowS
_showWideFlag Bool
flag = if Bool
flag then String -> ShowS
showString String
"L" else ShowS
forall a. a -> a
id

-- | get the haskell representation of a char constant
getCChar :: CChar -> String
getCChar :: CChar -> String
getCChar (CChar  Char
c Bool
_)   = [Char
c]
getCChar (CChars  String
cs Bool
_) = String
cs

-- | get integer value of a C char constant
-- undefined result for multi-char char constants
getCCharAsInt :: CChar -> Integer
getCCharAsInt :: CChar -> Integer
getCCharAsInt (CChar Char
c Bool
_) = Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
forall a. Enum a => a -> 36
Int -> Integer
forall a b. (I>String
Happy_IntList-> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (CFunctionDef aclass="annottext">a -&ga -ef="Language.C.Data.Node.html#nodeInfo">((_) = Chau: * -> *).
 (forall d b. Data d =&2t; c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -,; b) -> d 18">Chau: * -> *).
 (forall d b. Dan class="annot">String
cs

-- | get inspan id="line-65">cs
an> Stri58668"line-65">cs
an> Stri58668"line-65">"hs-glyph">|lass="annottext">Stri58668"line-65">cs
an>oc/ghc-doc/html9831"> (Char -> Int
forall a. Enum a => a -> 36
 class="hs-identifier hs-type">CTokGnuC css="an621679300178">> d -> class="annot">Node">a -&gcsisml"> n) = a
nStri58668"line-65">Doc -> Doc -> DoStri58668"line-6pan class="hs-glyph">="hs-var">cs
an>  n
<>Strall a b. (a ->ge.C.SyntreUnion a -> r)
-> (forall r r'.4var">csIdent CAsmExt >String -> Doc
text <>Strall a b. (a ->ge.C.SyntreUni:28><>Strall a b. (a ->ge.C.SyntreUni:28>s-identifier hs-var">f (Strall a b. (a ->ge.C.SyntreUni:28>s-identifier hs-var">f Doc -> Doc -> DoStri58668"line-6pan class="hs-glyph">="hs-var">csnnnnnn [CPartDesignator[s.html#%3A">:    pan>CExpression t1
_  pan>CExpression t1
CExpression t1
< la lass="hs-bdegt; d -> lass="hs-idegt; d ->– lass="hs8">String -> Doc
String -> Doc
=
< CExpressihiO)4pr3nnot"><">(aLength">< CExpressihiO)4pr3nnot"><">(aLength">< CExpressihiO)4pr3nnot"><">(aLength">< CExpressihiO)4pr3nnot"><">(aLength">< CExpressihiO)4pr3nnot"><">(aLenan>[ <00iden> -- | get the haskell representation of a char constant
getCChar--
-- This module pran id="line-61">=-- This module pran id="line-61">=-- This ss="hs-cpan>