debug-pp (empty) → 0.1.0.0
raw patch · 5 files changed
+191/−0 lines, 5 filesdep +basesetup-changed
Dependencies added: base
Files
- LICENSE +30/−0
- README.md +51/−0
- Setup.hs +2/−0
- debug-pp.cabal +31/−0
- src/Main.hs +77/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Pepe Iborra (c) 2017++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 Pepe Iborra 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,51 @@+[](https://travis-ci.org/pepeiborra/debug-pp)+[](https://hackage.haskell.org/package/debug-pp)+[](http://stackage.org/nightly/package/debug-pp)+# debug-pp++A preprocessor for streamlining the `debug` instrumentation of a module or a package.++Description+---------------++`debug-pp` is a Haskell source preprocessor that performs the steps a programmer would need to follow in order to debug a module with the [`debug`](http://hackage.haskell.org/package/debug) package. That is:+* append an import for the `Debug` module, and +* wrap the body in a `debug` splice using a TH declaration quasiquote. ++Usage+--------+```+usage: debug-pp [FILENAME] [SOURCE] [DEST]+Instrument Haskell module for debugging from SOURCE (derived from FILENAME) and write+standard Haskell to DEST.+If no FILENAME, use SOURCE as the original name.+If no DEST or if DEST is `-', write to standard output.+If no SOURCE or if SOURCE is `-', read standard input.+```+To instrument a module, add the following pragma to the top of the file:+```+{-# OPTIONS -F -pgmF debug-pp #-}+```++To instrument an entire program, add the following line to your stack descriptor, or if you don't use stack, to your cabal descriptor:+```+ghc-options: -F -pgmF debug-pp+```++In both cases you will also need to modify your Cabal descriptor in order to:+* add a dependency on the `debug` package, and+* add a build tool depends on `debug-pp` (required Cabal 2.0) :+```+Library+ ...+ build-tool-depends: debug-pp:debug-pp+```++Motivation+-------------++* Debugging individual functions is often impractical due to the declaration groups [restriction](http://ghc.readthedocs.io/en/8.0.1/glasgow_exts.html#ghc-flag--XTemplateHaskellQuotes) of Template Haskell. Therefore, it's often easier to debug an entire module.++* However, error messages are much worse for TH quoted code. Errors like `Not in scope: data constructor Foo in line X` become `Not in scope: Foo, in the TH quotation ENTIRE MODULE HERE`. ++* Personally, quoting/unquoting the module by hand is annoying. Having a preprocessor do this for me is convenient, and can be easily tied to a Cabal flag ora stack command line arg.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ debug-pp.cabal view
@@ -0,0 +1,31 @@+-- This file has been generated from package.yaml by hpack version 0.20.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 961f3a1ce57f79aa77bfe78b26a463a2bab8121dbb2e495de793608f4dc714e4++name: debug-pp+version: 0.1.0.0+description: A preprocessor to automate the debug instrumentation of a module+category: Debugging+homepage: https://github.com/pepeiborra/debug-hoed-pp#readme+author: Pepe Iborra+maintainer: pepeiborra@gmail.com+copyright: All Rights Reserved+license: BSD3+license-file: LICENSE+build-type: Simple+cabal-version: >= 1.10++extra-source-files:+ README.md++executable debug-pp+ main-is: Main.hs+ hs-source-dirs:+ src+ build-depends:+ base >=4.7 && <5+ other-modules:+ Paths_debug_pp+ default-language: Haskell2010
+ src/Main.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE ViewPatterns #-}++module Main (main) where++import Control.Monad+import Data.Char+import Data.List+import System.Environment+import System.Exit+import System.IO+import Text.Printf++usage :: String -> String+usage progName = unlines [+ "usage: " ++ progName +++ " [FILENAME] [SOURCE] [DEST]",+ "Instrument Haskell module for debugging from SOURCE (derived from FILENAME) and write",+ "standard Haskell to DEST.",+ "If no FILENAME, use SOURCE as the original name.",+ "If no DEST or if DEST is `-', write to standard output.",+ "If no SOURCE or if SOURCE is `-', read standard input."+ ]++main :: IO ()+main = do+ args <- getArgs+ progName <- getProgName+ (orig, inp, out) <- case args of+ ["--help"] -> do+ putStrLn $ usage progName+ exitSuccess+ [] -> return ("input",Nothing,Nothing)+ [i] -> return (i, Just i, Nothing)+ [i,o] -> return (i, Just i, Just o)+ [orig,i,o] -> return (orig, Just i, Just o)+ _ -> do+ putStrLn $ usage progName+ error "Unrecognized set of command line arguments"+ hIn <- maybe (return stdin) (`openFile` ReadMode) inp+ hOut <- maybe (return stdout) (`openFile` WriteMode) out+ contents <- hGetContents hIn+ hPutStr hOut $ instrument contents+ unless (hOut == stdout) $ hClose hOut++instrument contents = unlines [top', modules', body']+ where+ (top,modules,body) = parseModule contents+ modules' = unlines $ modules ++ ["import qualified Debug"]+ top' =+ unlines+ $ "{-# LANGUAGE TemplateHaskell #-}"+ : "{-# LANGUAGE PartialTypeSignatures #-}"+ : "{-# LANGUAGE ViewPatterns #-}"+ : "{-# OPTIONS -Wno-partial-type-signatures #-}"+ : top+ body' = unlines $ "Debug.debug [d|" : map indent (body ++ [" |]"])++parseModule contents = (top, modules, body)+ where+ isImportLine = ("import" `isPrefixOf`)+ (top, rest) = break isImportLine (lines contents)+ (reverse -> body0, reverse -> modules0) =+ break (isImportLine . fst) (reverse $ annotateBlockComments rest)+ body = map fst $ dropWhile snd body0+ modules = map fst modules0 ++ map fst (takeWhile snd body0)++indent it@('#':_) = it+indent other = " " ++ other++annotateBlockComments :: [String] -> [(String, Bool)]+annotateBlockComments = annotateBlockComments' False+annotateBlockComments' _ [] = []+annotateBlockComments' False (l:rest)+ | "{-" `isInfixOf` l = (l,True) : annotateBlockComments' True rest+ | otherwise = (l,False) : annotateBlockComments' False rest+annotateBlockComments' True (l:rest) =+ (l,True) : annotateBlockComments' (not $ "-}" `isInfixOf` l) rest