Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import System.Environment
- import System.IO
- import Data.List
- import System.Exit
- main = do
- args <- getArgs
- let combined = parseArgs args
- sep = separateFiles args
- fl = head (fst sep)
- showResultsFile fl (snd sep)
- showResultsFile :: String -> [String] -> IO ()
- showResultsFile fn flags = do
- res <- processFile fn flags
- putStrLn $ (unwords (map show res)) ++ " " ++ fn
- processFile :: String -> [String] -> IO [Int]
- processFile fl flags =
- mapM dispatch [(flag, fl) | flag <- flags]
- dispatch :: (String, String) -> IO Int
- dispatch ("--help", _) = showHelpAndExit
- dispatch ("--version", _) = showVersionAndExit
- dispatch (fl, fn) = do
- handle <- openFile fl ReadMode
- contents <- hGetContents handle
- let cnt = getCounter fn
- res = cnt contents
- hClose handle
- return res
- showHelpAndExit :: IO Int
- showHelpAndExit = do
- prog_name <- getProgName
- putStrLn ("Usage: " ++ prog_name ++ " [OPTION]... [FILE]...")
- putStrLn "Print newline, word and byte counts for each FILE,"
- putStrLn "and a total line if more than one FILE is specified."
- putStrLn " -c, --bytes print the byte counts"
- putStrLn " -m, --chars print the character counts"
- putStrLn " -l, --lines print the newline counts"
- putStrLn " -w, --words print the newline counts"
- putStrLn " --help display this help and exit"
- putStrLn " --version print version info and exit"
- exitSuccess
- showVersionAndExit :: IO Int
- showVersionAndExit = do
- prog_name <- getProgName
- putStrLn (prog_name ++ " 0.1")
- putStrLn "Licence info..."
- exitSuccess
- getCounter :: String -> String -> Int
- getCounter "--bytes" = countCharacters
- getCounter "--chars" = countCharacters
- getCounter "--lines" = countLines
- getCounter "--words" = countWords
- getCounter opt = error ("Unrecognized option: " ++ opt)
- parseArgs :: [String] -> [(String, String)]
- parseArgs args
- | null flags = [(file, flag) | flag <- ["--lines", "--words", "--bytes"], file <- files]
- | null files = [("", flag) | flag <- map normalizeFlags flags]
- | otherwise = [(file, flag) | flag <- map normalizeFlags flags, file <- files]
- where (files, flags) = separateFiles args
- normalizeFlags :: String -> String
- normalizeFlags "-c" = "--bytes"
- normalizeFlags "-m" = "--chars"
- normalizeFlags "-l" = "--lines"
- normalizeFlags "-w" = "--words"
- normalizeFlags x = x
- separateFiles :: [String] -> ([String], [String])
- separateFiles arguments
- | "--help" `elem` arguments = (["--help"], [])
- | "--version" `elem` arguments = (["--version"], [])
- | otherwise = partition (\ st -> head st /= '-') arguments
- countCharacters :: String -> Int
- countCharacters = length
- countLines :: String -> Int
- countLines = length . lines
- countWords :: String -> Int
- countWords = length . words
Advertisement
Add Comment
Please, Sign In to add comment