File: ConvertLibs.hs

package info (click to toggle)
hugs98 98.200311-4
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 12,964 kB
  • ctags: 8,084
  • sloc: ansic: 67,521; haskell: 61,497; xml: 4,566; sh: 3,264; cpp: 1,936; yacc: 1,094; makefile: 915; cs: 883; sed: 10
file content (197 lines) | stat: -rw-r--r-- 5,089 bytes parent folder | download | duplicates (7)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
--
-- Converting fptools/libraries/ into Hugs useable form.
--
module Main(main) where

import System
import IO
import Directory
import Maybe
import List
import Monad

cpp :: String
cpp = "gcc -P -E -xc -traditional"

wash :: FilePath -> FilePath -> String -> IO ()
wash inp outp extraArgs = do
  hPutStrLn stderr ("Pre-processing: " ++ inp)
  rc <- System.system cmd
  case rc of
    ExitSuccess   -> return ()
    ExitFailure{} -> hPutStrLn stderr ("Error: " ++ show rc)
 where 
  cmd = unwords [ cpp
  		, "-D__HUGS__"
		, "-D__HASKELL98__"
		, extraArgs
		, inp
		, "-o " ++ outp
		] 

outDir :: String
outDir = "c:/src/hugs98/libraries"

inpDir :: String
inpDir = "c:/fptools/HEAD/libraries"

pathSeparator :: Char
pathSeparator = '/'

isPathSeparator :: Char -> Bool
isPathSeparator '/'  = True
isPathSeparator '\\' = True
isPathSeparator _    = False


main :: IO ()
main = do
  putStrLn "Converting the Haskell hierarchical libraries into Hugs friendly form"
  putStrLn ("Source directory: " ++ inpDir)
  putStrLn ("Output directory: " ++ outDir)
  isThere <- doesDirectoryExist inpDir
  when (not isThere)
       (hPutStrLn stderr "input directory does not exist, stopping." >> exitSuccess)
  isThere <- doesDirectoryExist outDir
  when (not isThere)
       (hPutStrLn stderr "output directory does not exist, stopping." >> exitSuccess)
  fs <- findAllFilesMatching pathFilter fileFilter inpDir
  print "done"
  let theFs = mapMaybe ofInterest fs
  mapM_ washFile theFs
  return ()
 where
      pathFilter :: [FilePath] -> Bool
      pathFilter []        = True
      pathFilter ("CVS":_) = False
      pathFilter fs@(x:_) | "_split" `isSuffixOf` x = False
      pathFilter _ = True

      fileFilter :: [FilePath] -> Bool
      fileFilter = withSuffix ["hs", "lhs"]

      ofInterest :: [String] -> Maybe ([String], Maybe String)
      ofInterest comps = Just (comps, Nothing)

      washFile (comps, mbArgs) = do
	 makeDirectory oDir
         wash (inpDir ++ pathSeparator : relNm)
	      (outDir ++ pathSeparator : relNm)
	      (fromMaybe "" mbArgs)
       where
	  rcomps = reverse comps
	  relDir = concat (intersperse [pathSeparator] (reverse (tail comps)))
	  relNm  = concat (intersperse [pathSeparator] rcomps)

	  oDir   = outDir ++ pathSeparator:relDir

exitSuccess = exitWith ExitSuccess


{-
  Given a base directory, locate all files satisfying 'pred' in
  that directory tree.
  
  The files returned are all in 
-}  
findAllFilesMatching :: ([String] -> Bool)
		     -> ([String] -> Bool)
		     -> FilePath
		     -> IO [[String]]
findAllFilesMatching predPath predFile base = go []
 where
   go prefix = do
     ls <- getDirectoryContents fPath
     let entries = filter (not.isHereUp) ls
     stuff <- mapM (\ f -> classifyEntry (f:prefix) (mkFilePath base prefix f)) entries

     let (dirs, allFiles) = unzipEithers stuff
         theFiles         = filter predFile allFiles

     print theFiles
     lss <- mapM go (filter predPath dirs)
     return (theFiles ++ concat lss)
    where
     fPath = mkFilePath base prefix ""

makeDirectory :: FilePath -> IO ()
makeDirectory fpath = do
  flg <- doesDirectoryExist fpath
  print (fpath,flg,dirName fpath)
  if flg
   then return ()
   else do
       -- try creating the parent.
     case dirName fpath of
       ""   -> createDirectory fpath
       "./" -> createDirectory fpath
       d  -> do
         flg <- doesDirectoryExist d
         when (not flg) (makeDirectory d)
         createDirectory fpath	   

classifyEntry f fpath = do
  flg <- doesDirectoryExist fpath
  return ((case flg of { True -> Left; _ -> Right}) f)


mkFilePath :: FilePath -> [String] -> String -> FilePath
mkFilePath base comps s = foldr (\ x acc -> acc ++ pathSeparator:x) base (consL s comps)
 where
   consL [] xs = xs
   consL x  xs = x:xs

isHereUp :: FilePath -> Bool
isHereUp "."  = True
isHereUp ".." = True
isHereUp _    = False

unzipEithers :: [Either a b] -> ([a], [b])
unzipEithers [] = ([], [])
unzipEithers (x:xs) = 
  case x of
    Left  v -> (v:as, bs)
    Right v -> (as, v:bs)
 where
  (as,bs)   = unzipEithers xs

withSuffix :: [String] -> [String] -> Bool
withSuffix _ []       = False
withSuffix sufs (s:_) = fileSuffix s `elem` sufs

hasSuffix [] = False
hasSuffix (x:_) = not (null (fileSuffix x))

-- FileUtil outtakes:

dirName :: FilePath -> FilePath
dirName fname =
  case revDropWhile (not.isPathSeparator) (revDropWhile isPathSeparator fname) of
    "" -> "./" -- no separator was found, dir-name is "."
    xs -> xs

revDropWhile :: (a -> Bool) -> [a] -> [a]
revDropWhile p = foldr f []
  where f x [] = if p x then [] else [x]
        f x xs = (x:xs)

-- suffix _does not_ include the dot. In case there isn't a suffix,
-- return empty string.
fileSuffix :: FilePath -> String
fileSuffix = findLast (=='.') "" 

findLast :: (Char -> Bool)
	 -> String
	 -> String
	 -> String
findLast pred noMatch f = go False f f
  where
    go matched acc [] 
      | matched   = acc
      | otherwise = noMatch
    go matched acc (x:xs)
      | pred x    = go True xs xs
      | otherwise = go matched acc xs