pmksb98

word-count

Jun 24th, 2011
172
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import System.Environment
  2. import System.IO
  3. import Data.List
  4. import System.Exit
  5.  
  6. main = do
  7.   args <- getArgs
  8.   let combined = parseArgs args
  9.       sep = separateFiles args
  10.       fl = head (fst sep)
  11.   showResultsFile fl (snd sep)
  12.  
  13. showResultsFile :: String -> [String] -> IO ()
  14. showResultsFile fn flags = do
  15.   res <- processFile fn flags
  16.   putStrLn $ (unwords (map show res)) ++ " " ++ fn
  17.  
  18. processFile :: String -> [String] -> IO [Int]
  19. processFile fl flags =
  20.   mapM dispatch [(flag, fl) | flag <- flags]
  21.  
  22. dispatch :: (String, String) -> IO Int
  23. dispatch ("--help", _) = showHelpAndExit
  24. dispatch ("--version", _) = showVersionAndExit
  25. dispatch (fl, fn) = do
  26.   handle <- openFile fl ReadMode
  27.   contents <- hGetContents handle
  28.   let cnt = getCounter fn
  29.       res = cnt contents
  30.   hClose handle
  31.   return res
  32.  
  33. showHelpAndExit :: IO Int
  34. showHelpAndExit = do
  35.   prog_name <- getProgName
  36.   putStrLn ("Usage: " ++ prog_name ++ " [OPTION]... [FILE]...")
  37.   putStrLn "Print newline, word and byte counts for each FILE,"
  38.   putStrLn "and a total line if more than one FILE is specified."
  39.   putStrLn "  -c, --bytes      print the byte counts"
  40.   putStrLn "  -m, --chars      print the character counts"
  41.   putStrLn "  -l, --lines      print the newline counts"
  42.   putStrLn "  -w, --words      print the newline counts"
  43.   putStrLn "      --help       display this help and exit"
  44.   putStrLn "      --version    print version info and exit"
  45.   exitSuccess
  46.  
  47. showVersionAndExit :: IO Int
  48. showVersionAndExit = do
  49.   prog_name <- getProgName
  50.   putStrLn (prog_name ++ " 0.1")
  51.   putStrLn "Licence info..."
  52.   exitSuccess
  53.  
  54.  
  55. getCounter :: String -> String -> Int
  56. getCounter "--bytes" = countCharacters
  57. getCounter "--chars" = countCharacters
  58. getCounter "--lines" = countLines
  59. getCounter "--words" = countWords
  60. getCounter opt = error ("Unrecognized option: " ++ opt)
  61.  
  62. parseArgs :: [String] -> [(String, String)]
  63. parseArgs args
  64.   | null flags = [(file, flag) | flag <- ["--lines", "--words", "--bytes"], file <- files]
  65.   | null files = [("", flag) | flag <- map normalizeFlags flags]
  66.   | otherwise  = [(file, flag) | flag <- map normalizeFlags flags, file <- files]
  67.   where (files, flags) = separateFiles args
  68.  
  69. normalizeFlags :: String -> String
  70. normalizeFlags "-c" = "--bytes"
  71. normalizeFlags "-m" = "--chars"
  72. normalizeFlags "-l" = "--lines"
  73. normalizeFlags "-w" = "--words"
  74. normalizeFlags x = x
  75.  
  76. separateFiles :: [String] -> ([String], [String])
  77. separateFiles arguments
  78.   | "--help" `elem` arguments    = (["--help"], [])
  79.   | "--version" `elem` arguments = (["--version"], [])
  80.   | otherwise = partition (\ st -> head st /= '-') arguments
  81.  
  82. countCharacters :: String -> Int
  83. countCharacters = length
  84.  
  85. countLines :: String -> Int
  86. countLines = length . lines
  87.  
  88. countWords :: String -> Int
  89. countWords = length . words
RAW Paste Data