hsb2hs (empty) → 0.1
raw patch · 4 files changed
+118/−0 lines, 4 filesdep +basedep +bytestringdep +containerssetup-changed
Dependencies added: base, bytestring, containers, directory, filepath, preprocessor-tools
Files
- LICENSE +30/−0
- Setup.lhs +3/−0
- hsb2hs.cabal +25/−0
- hsb2hs.hs +60/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c)2010, John MacFarlane++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 John MacFarlane 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.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ hsb2hs.cabal view
@@ -0,0 +1,25 @@+Name: hsb2hs+Version: 0.1+Synopsis: Preprocesses a file, adding blobs from files as string literals.+Description:+ hsb2hs is a preprocessor that allows you to include the contents of+ files as string literals in your Haskell programs and libraries.+ It is an alternative to file-embed for those who do not want to rely+ on Template Haskell. See @README.markdown@ for instructions.++License: BSD3+License-file: LICENSE+Author: John MacFarlane+Maintainer: jgm@berkeley.edu+Copyright: Copyright (C) 2013 John MacFarlane+Category: Development+Cabal-version: >=1.6+Build-type: Simple+Source-repository head+ type: git+ location: git://github.com/jgm/hsb2hs.git+Executable hsb2hs+ Main-is: hsb2hs.hs+ Ghc-Options: -Wall+ Build-depends: base >= 4 && < 5, containers, bytestring, directory,+ filepath, preprocessor-tools > 0.1 && < 0.2
+ hsb2hs.hs view
@@ -0,0 +1,60 @@+module Main+where+import Language.Haskell.Preprocessor+import System.IO.Unsafe (unsafePerformIO)++import qualified Data.ByteString as B+import System.Directory+import System.Environment (getArgs)+import Control.Arrow ((&&&), second)+import Control.Applicative ((<$>))+import Control.Monad+import System.FilePath++main :: IO ()+main = do+ args <- getArgs+ transform blobExtension args++blobExtension :: Extension+blobExtension = base{+ transformer = processBlobs+}++processBlobs :: [Ast] -> [Ast]+processBlobs [] = []+processBlobs (Single (Token Operator _ l "%") :+ Single (Token Variable _ _ kw) :+ Single (Token StringLit _ _ lit) :+ xs) | kw == "blobs" || kw == "blob" =+ (Single (Token StringLit [] l (getLiteral $ stripQuotes lit))) :+ processBlobs xs+ where stripQuotes = reverse . stripLeadingQuote . reverse . stripLeadingQuote+ stripLeadingQuote ('"':ys) = ys+ stripLeadingQuote ys = ys+ getLiteral f = unsafePerformIO $ if kw == "blob"+ then show `fmap` B.readFile f+ else show `fmap` fileList' f ""+processBlobs (x:xs) =+ (case x of+ Single tok -> Single tok+ Block i l b r n -> Block i l (processBlobs b) r n+ Empty -> Empty) : processBlobs xs++-- fileList' is taken from Michael Snoyman's file-embed+fileList' :: FilePath -> FilePath -> IO [(FilePath, B.ByteString)]+fileList' realTop top = do+ allContents <- filter notHidden <$> getDirectoryContents (realTop </> top)+ let all' = map ((top </>) &&& (\x -> realTop </> top </> x)) allContents+ files <- filterM (doesFileExist . snd) all' >>=+ mapM (liftPair2 . second B.readFile)+ dirs <- filterM (doesDirectoryExist . snd) all' >>=+ mapM (fileList' realTop . fst)+ return $ concat $ files : dirs++notHidden :: FilePath -> Bool+notHidden ('.':_) = False+notHidden _ = True++liftPair2 :: Monad m => (a, m b) -> m (a, b)+liftPair2 (a, b) = b >>= \b' -> return (a, b')