File: Cpphs.hs

package info (click to toggle)
cpphs 0.7-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 360 kB
  • ctags: 18
  • sloc: haskell: 939; makefile: 79; sh: 36; ansic: 11
file content (48 lines) | stat: -rw-r--r-- 1,867 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{-
-- The main program for cpphs, a simple C pre-processor written in Haskell.

-- Copyright (c) 2004 Malcolm Wallace
-- This file is GPL, although the libraries it uses are either standard
-- Haskell'98 or distributed under the LGPL.
-}
module Cpphs ( runCpphs ) where
import System   (exitWith, ExitCode(..))
import List     (isPrefixOf)
import Monad    (when)
import IO       (stdout, IOMode(WriteMode), openFile, hPutStr)

import CppIfdef (cppIfdef)
import MacroPass(macroPass)

version :: String
version = "0.7"

runCpphs :: String -> [String] -> IO ()
runCpphs prog args = do
  let ds    = map (drop 2) (filter ("-D"`isPrefixOf`) args)
      os    = map (drop 2) (filter ("-O"`isPrefixOf`) args)
      is    = map (trail "/\\" . drop 2) (filter ("-I"`isPrefixOf`) args)
      macro = not ("--nomacro" `elem` args)
      locat = not ("--noline" `elem` args)
      strip =      "--strip" `elem` args
      ansi  =      "--hashes" `elem` args
      layout=      "--layout" `elem` args
      files = filter (not . isPrefixOf "-") args
  when ("--version" `elem` args)
       (do putStrLn (prog++" "++version)
           exitWith ExitSuccess)
  when (null files || length os > 1)
       (do putStrLn ("Usage: "++prog
                ++" file ... [ -Dsym | -Dsym=val | -Ipath ]*  [-Ofile]\n"
                ++"\t\t[--nomacro] [--noline] [--strip] [--hashes] [--layout]")
           exitWith (ExitFailure 1))
  o <- if null os then return stdout else openFile (head os) WriteMode
  mapM_ (\f-> do c <- readFile f
                 let pass1 = cppIfdef f ds is macro locat c
                     pass2 = macroPass ds strip ansi layout pass1
                 if not macro then hPutStr o (unlines (map snd pass1))
                              else hPutStr o pass2
        ) files

trail :: (Eq a) => [a] -> [a] -> [a]
trail xs = reverse . dropWhile (`elem`xs) . reverse