| 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
49
50
51
52
53
 | 
module MakeFile ( MakeFile, MakeElement(..), SpecialTarget(..)
                , showMakeFile ) where
import List ( intercalate )
type MakeFile = [MakeElement]
data MakeElement = DefineVariable String [String]
                 | Rule [SpecialTarget] String [String] [String]
                 |  String
                 | Empty
data SpecialTarget = PHONY | NOTPARALLEL
showMakeFile :: MakeFile -> String
showMakeFile = unlines . map showMakeElement
showMakeElement :: MakeElement -> String
showMakeElement Empty = ""
showMakeElement (Comment s) = "# " ++ s
showMakeElement (DefineVariable name values) =
  name ++ " = " ++ intercalate " \\\n\t  " (unwordsUpTo 70 values)
showMakeElement (Rule specials target prereqs actions) = unlines $
  map (\s -> showSpecialTarget s ++ ": " ++ target) specials ++
  [target ++ ": " ++ intercalate " \\\n\t  " (unwordsUpTo 70 prereqs) ] ++
  map ("\t"++) actions
showSpecialTarget :: SpecialTarget -> String
showSpecialTarget st = '.' : show st
unwordsUpTo :: Int -> [String] -> [String]
unwordsUpTo max words = fillWords 0 "" words
 where
  fillWords _ s [] = [s]
  fillWords n s (w:ws) =
    let nw = n + length w
    in if nw < max || n==0 
         then fillWords (nw+1) (s ++ (if n==0 then "" else " ") ++ w) ws
         else s : fillWords 0 "" (w:ws)
 |