scan (empty) → 0.1.0.0
raw patch · 4 files changed
+133/−0 lines, 4 filesdep +basedep +parsecsetup-changed
Dependencies added: base, parsec
Files
- Setup.hs +2/−0
- doc/LICENSE +0/−0
- scan.cabal +47/−0
- src/scan.hs +84/−0
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ doc/LICENSE view
+ scan.cabal view
@@ -0,0 +1,47 @@+cabal-version: >= 1.6+build-type: Simple+name: scan+version: 0.1.0.0+license: BSD3+license-file: doc/LICENSE+category: Development+author: chr.maeder@web.de+maintainer: chr.maeder@web.de+copyright: Christian Maeder 2010+synopsis: lexical style suggestions for source code+description:+ scan checks the format of your source code. It reports+ (and partly repairs if given the @-@ option):++ non-ascii characters,+ tabs or carriage returns,+ trailing white spaces,+ backslash at line end,+ unconventional comment delimiters,+ too long lines,+ too many consecutive blank lines,+ not a single blank between tokens,+ not a single final newline,+ no spaces after commas,+ spaces between parens and infix operators in sections,+ bad layout (wrt @do@ or @of@).++ It may be useful in conjunction with+ <http://community.haskell.org/~ndm/hlint/>+ to give suggestions on how to improve your source code.++ Repairing is not suited for slices (aka @$(...)@) in template haskell or if+ you like to align your code at @=@ or @->@ in the middle of a line (thus+ wanting multiple blanks). Furthermore layout may be destroyed by inserting+ or deleting blanks, but this is an indication for improving layout anyway.+ Also lines may become too long after inserting blanks.++homepage: http://projects.haskell.org/style-scanner+stability: experimental++executable scan+ build-depends: base < 5, parsec < 3 || >= 3+ hs-source-dirs: src+ main-is: scan.hs++ ghc-options: -Wall
+ src/scan.hs view
@@ -0,0 +1,84 @@+{- |+Module : scan.hs+Description : the standalone Haskell style scanner+Copyright : (c) Christian Maeder 2010+License : BSD++Maintainer : chr.maeder@web.de+Stability : experimental+Portability : portable++the Haskell style scanner+-}++module Main where++import Control.Monad++import Data.Char+import Data.List++import System.Environment+import Text.ParserCombinators.Parsec++import Language.Haskell.Scanner++main :: IO ()+main = do+ args <- getArgs+ let (opts, files) = span (== "-") args+ b = null opts+ case files of+ [] -> putStrLn "missing file argument"+ _ -> mapM_ (process $ null opts) $ if b then files else+ take 3 files -- do not spoil more than 3 files++process :: Bool -> String -> IO ()+process b f = do+ str <- readFile f+ let nls = zip [1 ..] $ lines str+ bls = checkBlankLines f 1 nls+ when b $ mapM_ (checkLine f) nls+ when (b && not (isSuffixOf "\n" str))+ $ diag f (length nls) "missing final newline"+ when b $ mapM_ putStrLn bls+ case parse scan f str of+ Right ts -> let x = splitLines ts in+ if b then let o = showScan x in unless (null o) $ putStrLn o else+ let rstr = processScan x in+ if rstr == str then putStrLn $ "no changes in \"" ++ f ++ "\"" else do+ writeFile (f ++ ".bak") str+ writeFile f rstr+ putStrLn $ "updated \"" ++ f ++ "\" (and created .bak)"+ Left err -> fail $ show err++checkBlankLines :: FilePath -> Int -> [(Int, String)] -> [String]+checkBlankLines f c l = case l of+ [] -> if c > 0 then ["trailing blank lines"] else []+ (n, s) : r ->+ if null $ filter (not . isSpace) s then+ if c >= 2 then+ diagStr f n "too many consecutive blank lines"+ : checkBlankLines f (- 100) r+ else checkBlankLines f (c + 1) r+ else checkBlankLines f 0 r++diagStr :: FilePath -> Int -> String -> String+diagStr f n str = "\"" ++ f ++ "\" (line " ++ show n ++ ") " ++ str++diag :: FilePath -> Int -> String -> IO ()+diag f n = putStrLn . diagStr f n++checkLine :: FilePath -> (Int, String) -> IO ()+checkLine f (n, s) = do+ let r = reverse s+ rt = dropWhile isSpace r+ l = length rt+ trailBSlash = takeWhile (== '\\') rt+ badChars = filter (\ c -> not $ isAscii c && isPrint c) s+ when (l > 80) $+ diag f n $ "too long line (" ++ show l ++ " chars)"+ unless (null badChars) $+ diag f n $ "contains undesirable characters: " ++ show badChars+ unless (null trailBSlash) $+ diag f n "back slash at line end (may disturb cpp)"