packages feed

cppfilt (empty) → 0.1.0.0

raw patch · 10 files changed

+312/−0 lines, 10 filesdep +basedep +bytestringdep +cppfiltsetup-changed

Dependencies added: base, bytestring, cppfilt, criterion, hspec

Files

+ ChangeLog.md view
@@ -0,0 +1,3 @@+# Changelog for cppfilt++## Unreleased changes
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Georg Rudoy (c) 2018++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Author name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,21 @@+# cppfilt++[![Build Status](https://travis-ci.org/0xd34df00d/cppfilt.svg?branch=master)](https://travis-ci.org/0xd34df00d/cppfilt)++This library provides bindings to the system ABI-exposed C++ name demangling+routines. It provides both `IO`-based API in the `System.Demangle` module+and the pure one in `System.Demangle.Pure`. The latter is deduced as unsafe+due to `unsafePerformIO` (which should be fine, though, since demangling is+hopefully referentially transparent).+++## Supported systems++For now demangling is done using either `libstdc++` or `libc++` (controlled+via the `use-libcpp` build flag). Adding support for other ABIs in a similar+fashion should be easy.++This approach is probably suboptimal, though, since one might want to try+different ABIs that might be available simultaneously (since even clang and+gcc mangle some names slightly differently), but it's not entirely obvious+what the API should be like in this case.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bench/Bench.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications #-}++import Criterion.Main+import Data.ByteString(ByteString)+import Data.String++import qualified System.Demangle as D++testData :: IsString a => [(String, a)]+testData = [+    ("simple", "_ZTI5IInfo"),+    ("operator", "_ZrsR11QDataStreamR5QUuid"),+    ("complex", "_ZTSZN10LeechCraft4Util15InstanceFunctorI7QFutureINS0_6EitherIN5boost7variantIN5vmime10exceptions20authentication_errorEJNS7_16connection_errorENS6_8security4cert20certificateExceptionENS_6Snails23GenericExceptionWrapperEEEENSD_19AccountThreadWorker10SyncResultEEEEE5ApplyINS0_7VisitorINS0_4VoidEJZNSD_7Account15SynchronizeImplERK5QListI11QStringListERK10QByteArrayNSD_12TaskPriorityEE3$_1ZNSO_15SynchronizeImplEST_SW_SX_E3$_2EEEEES2_INSt5decayINSt9result_ofIFT_SI_EE4typeEE4typeEERKSJ_RKS13_EUlRKSI_E_"),+    ("rly complex", "_ZN5boost6detail7variant15visitation_implIN4mpl_4int_ILi0EEENS1_20visitation_impl_stepINS_3mpl6l_iterINS7_6l_itemINS3_5long_ILl7EEEN5vmime10exceptions20authentication_errorENS9_INSA_ILl6EEENSD_16connection_errorENS9_INSA_ILl5EEENSC_8security4cert20certificateExceptionENS9_INSA_ILl4EEEN10LeechCraft6Snails23GenericExceptionWrapperENS9_INSA_ILl3EEENSN_15MessageNotFoundENS9_INSA_ILl2EEENSN_13FileOpenErrorENS9_INSA_ILl1EEENSN_18AttachmentNotFoundENS7_5l_endEEEEEEEEEEEEEEEEENS8_ISV_EEEENS1_14invoke_visitorINSM_4Util6detail7VisitorIvJZZNSN_10ThreadPool20PerformScheduledFuncI16QFutureInterfaceINS17_6EitherINS_7variantISE_JSG_SK_SO_SQ_SS_SU_EEENS17_4VoidEEEEMNSN_19AccountThreadWorkerEFNS1D_INS1E_ISQ_JSS_SU_EEES1G_EESt10shared_ptrINSN_7MessageEERK7QStringS1R_EJS1O_S1P_S1P_EEEvPNSN_13AccountThreadET_NSN_12TaskPriorityERKT0_DpRKT1_ENUlS1W_E_clIS1H_EEDaS1W_EUlRKSE_E_ZZNS1B_IS1I_S1T_JS1O_S1P_S1P_EEEvS1V_S1W_S1X_S20_S24_ENS26_IS1H_EEDaS1W_EUlS1W_E_EEEEEPKvNS1F_18has_fallback_type_EEENT1_11result_typeEiiRS2G_T2_NS3_5bool_ILb0EEET3_PS1W_PS1Y_")+  ]++main :: IO ()+main = defaultMain [+    bgroup "demangle string"     [ bench name $ nfIO $ D.demangle @String mangled | (name, mangled) <- testData],+    bgroup "demangle bytestring" [ bench name $ nfIO $ D.demangle @ByteString mangled | (name, mangled) <- testData]+  ]
+ cppfilt.cabal view
@@ -0,0 +1,83 @@+-- This file has been generated from package.yaml by hpack version 0.20.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: e0c10543991dcafe3f792b8d89a01a6778270aebbde0275b126c27a106b7366f++name:           cppfilt+version:        0.1.0.0+synopsis:       Bindings for C++ demangling routines+description:    Please see the README on Github at <https://github.com/0xd34df00d/cppfilt#readme>+category:       System+homepage:       https://github.com/0xd34df00d/cppfilt#readme+bug-reports:    https://github.com/0xd34df00d/cppfilt/issues+author:         Georg Rudoy+maintainer:     0xd34df00d@gmail.com+copyright:      2018 Georg Rudoy+license:        BSD3+license-file:   LICENSE+build-type:     Simple+cabal-version:  >= 1.10++extra-source-files:+    ChangeLog.md+    README.md++source-repository head+  type: git+  location: https://github.com/0xd34df00d/cppfilt++flag use-libcpp+  description: Use libc++ for demangling (if you're building your C++ code with clang) instead of libstdc+++  manual: True+  default: False++library+  hs-source-dirs:+      src+  build-depends:+      base >=4.7 && <5+    , bytestring+  if flag(use-libcpp) || os(darwin)+    extra-libraries:+        c+++  else+    extra-libraries:+        stdc+++  exposed-modules:+      Data.CStringRepresentable+      System.Demangle+      System.Demangle.Pure+  other-modules:+      Paths_cppfilt+  default-language: Haskell2010++test-suite cppfilt-test+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      base >=4.7 && <5+    , bytestring+    , cppfilt+    , hspec+  other-modules:+      Paths_cppfilt+  default-language: Haskell2010++benchmark cppfilt-benchmarks+  type: exitcode-stdio-1.0+  main-is: Bench.hs+  hs-source-dirs:+      bench+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      base >=4.7 && <5+    , bytestring+    , cppfilt+    , criterion+  other-modules:+      Paths_cppfilt+  default-language: Haskell2010
+ src/Data/CStringRepresentable.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE FlexibleInstances #-}++{-|+ Module      : Data.CStringRepresentable+ Description : Type class for string-like objects nicely mapping to 'CString's+ Stability   : experimental++ This module provides the type class (and a few implementations) for values that+ can be efficiently converted to/from 'CString'. Instances for 'String' and+ strict 'BS.ByteString' are provided, and the use of 'BS.ByteString' is+ recommended if performance is a concern.+ -}++module Data.CStringRepresentable where++import qualified Data.ByteString.Char8 as BS+import Foreign.C++-- | Represents values that can be efficiently converted to and from 'CString's.+class CStringRepresentable a where+  -- | Perform a function on the 'CString' representation of the value.+  toCString :: a -> (CString -> IO b) -> IO b+  -- | Convert 'CString' to a value of the type. The ownership is not transferred.+  fromCString :: CString -> IO a++-- | 'String's can be represented as 'CString's (albeit conversions are inefficient).+instance CStringRepresentable String where+  toCString = withCString+  fromCString = peekCString++-- | 'BS.ByteString's can be represented as 'CString's.+instance CStringRepresentable BS.ByteString where+  toCString = BS.useAsCString+  fromCString = BS.packCString
+ src/System/Demangle.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE ForeignFunctionInterface #-}++{-|+ Module      : System.Demangle+ Description : Functions for demangling C++ names+ Stability   : experimental+ Portability : wherever gcc lives++ This module provides bindings to the platform C++ ABI demangling routines+ (where the platform is currently limited to gcc). Any string-like type+ implementing 'CStringRepresentable' can be used, though strict bytestrings are+ the most performant.++ This module provides the raw 'IO'-living functions. Thin wrappers pretending+ to be pure live in the "System.Demangle.Pure" module.+ -}++module System.Demangle(demangle) where++import qualified Data.ByteString.Char8 as BS+import Control.Exception++import Foreign.C+import Foreign.Marshal.Alloc+import Foreign.Ptr++import Data.CStringRepresentable++foreign import ccall "__cxa_demangle"+  cxa_demangle :: CString -> CString -> Ptr CSize -> Ptr CInt -> IO CString++-- |Try to demangle a mangled C++ name.+demangle :: CStringRepresentable s => s -> IO (Maybe s)+demangle str = toCString str $ \str' ->+  bracket+    (cxa_demangle str' nullPtr nullPtr nullPtr)+    free+    $ \res ->+      if res == nullPtr+        then pure Nothing+        else do+          res' <- fromCString res+          pure $ Just res'
+ src/System/Demangle/Pure.hs view
@@ -0,0 +1,26 @@+{-|+ Module      : System.Demangle.Pure+ Description : Functions for demangling C++ names pretending to be pure+ Stability   : experimental+ Portability : wherever gcc lives++ This module provides bindings to the platform C++ ABI demangling routines+ (where the platform is currently limited to gcc). Any string-like type+ implementing 'CStringRepresentable' can be used, though strict bytestrings are+ the most performant.++ This module provides the pure-ish functions which hide the intrinsic 'IO'+ nature of doing FFI calls behind 'unsafePerformIO'. Demangling is+ referentially transparent, though, so that should be fine.+ -}++module System.Demangle.Pure where++import System.IO.Unsafe++import qualified System.Demangle as D+import Data.CStringRepresentable++-- |Try to demangle a mangled C++ name.+demangle :: CStringRepresentable s => s -> Maybe s+demangle = unsafePerformIO . D.demangle
+ test/Spec.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeApplications #-}++import Test.Hspec++import qualified Data.ByteString.Char8 as BS+import Data.String+import Control.Monad++import qualified System.Demangle as D+import qualified System.Demangle.Pure as DP++import Data.CStringRepresentable++ioDemangledIs :: (Eq a, Show a, CStringRepresentable a) => a -> Maybe a -> IO ()+ioDemangledIs mangled ref = do+  res <- D.demangle mangled+  res `shouldBe` ref++pureDemangledIs :: (Eq a, Show a, CStringRepresentable a) => a -> Maybe a -> IO ()+pureDemangledIs mangled ref = DP.demangle mangled `shouldBe` ref++testData :: IsString a => [(String, [(a, Maybe a)])]+testData = [+    ("demangles simple class names", [+        ("_ZTS5IInfo", Just "typeinfo name for IInfo")+      ]),+    ("demangles some operators", [+        ("_ZrsR11QDataStreamR5QUuid", Just "operator>>(QDataStream&, QUuid&)")+      ]),+    ("demangle fails", [+        ("_test", Nothing)+      ])+  ]++runTests :: IsString a => (a -> Maybe a -> IO ()) -> SpecWith ()+runTests func =+  forM_ testData $ \(str, pairs) ->+    it str $ forM_ pairs $ uncurry func++main :: IO ()+main = hspec $ do+  describe "Strings" $ do+    describe "IO demangle" $ runTests @String ioDemangledIs+    describe "Pure demangle" $ runTests @String pureDemangledIs+  describe "ByteStrings" $ do+    describe "IO demangle" $ runTests @BS.ByteString ioDemangledIs+    describe "Pure demangle" $ runTests @BS.ByteString pureDemangledIs