packages feed

clang-pure-0.2.0.2: examples/ListStructs.hs

{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}

import           Language.C.Clang
import           Language.C.Clang.Cursor.Typed
import           Control.Lens
import qualified Data.ByteString.Char8 as BS
import           Data.Monoid
import           Data.Word
import           System.Environment

data CField = CField
  { cFieldName :: BS.ByteString
  , cFieldOffset :: Word64
  , cFieldType :: Type
  } deriving (Show)

data CStruct = CStruct
  { cStructName :: BS.ByteString
  , cStructFields :: [ CField ]
  } deriving (Show)

main :: IO ()
main = do
  args <- getArgs
  case args of
    path : clangArgs -> do
      idx <- createIndex
      tu <- parseTranslationUnit idx path clangArgs

      let toCField fieldDecC = do
            offset <- offsetOfField fieldDecC
            return $ CField
              { cFieldName = cursorSpelling fieldDecC
              , cFieldOffset = offset
              , cFieldType = cursorType fieldDecC
              }

      let toCStruct structDecC = do
            let fieldDecs =
                  structDecC
                    ^.. cursorDescendantsF
                      . folding (matchKind @'FieldDecl)
            cFields <- traverse toCField fieldDecs
            return $ CStruct (cursorSpelling structDecC) cFields

      let cStructs =
            translationUnitCursor tu
              ^.. cursorDescendantsF
                . folding (matchKind @'StructDecl)
                . to toCStruct
                . _Right

      print cStructs

    _ -> putStrLn "usage: list-structs path [clang opts]"