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
  | 
module REPL.RCFile
  ( readRC, rcValue, setRCProperty, extractRCArgs, updateRCDefs )
 where
import Control.Monad     ( unless )
import Data.Char         ( toLower, isSpace )
import Data.List         ( isPrefixOf, partition, sort )
import Data.PropertyFile
import System.FilePath   ( FilePath, (</>), (<.>) )
import System.Directory  ( getHomeDirectory, doesFileExist, copyFile
                         , renameFile )
import REPL.Compiler
import REPL.PkgConfig    ( packagePath )
import REPL.Utils        ( strip )
getDefaultRC :: CCDescription -> IO FilePath
getDefaultRC cd = do
  let cmprc = ccHome cd </> ccName cd ++ "rc.default"
  excmprc <- doesFileExist cmprc
  if excmprc then return cmprc
             else return (packagePath </> "curryrc.default")
rcFileName :: CCDescription -> IO FilePath
rcFileName cd = (</> "." ++ ccName cd ++ "rc") `fmap` getHomeDirectory
readRC :: CCDescription -> IO [(String, String)]
readRC cd = do
  rcname <- rcFileName cd
  rcdefname <- getDefaultRC cd
  rcexists  <- doesFileExist rcname
  catch (if rcexists
           then updateRC cd rcdefname
           else do putStrLn $ "Installing '" ++ rcname ++ "'..."
                   copyFile rcdefname rcname)
        (const $ return ())
  readPropertyFile rcname
rcKeys :: [(String, String)] -> [String]
rcKeys = sort . map fst
updateRC :: CCDescription -> String -> IO ()
updateRC cd defaultrc = do
  rcname    <- rcFileName cd
  userprops <- readPropertyFile rcname
  distprops <- readPropertyFile defaultrc
  unless (rcKeys userprops == rcKeys distprops) $ do
    putStrLn $ "Updating '" ++ rcname ++ "'..."
    renameFile rcname $ rcname <.> "bak"
    copyFile defaultrc rcname
    mapM_ (\ (n, v) -> maybe (return ())
             (\uv -> unless (uv == v) $ updatePropertyFile rcname n uv)
             (lookup n userprops))
          distprops
setRCProperty :: CCDescription -> String -> String -> IO ()
setRCProperty cd pname pval = do
  readRC cd 
  rcname <- rcFileName cd
  updatePropertyFile rcname pname pval
rcValue :: [(String, String)] -> String -> String
rcValue rcdefs var = strip $ maybe "" id $
  lookup (map toLower var) (map (first (map toLower)) rcdefs)
 where
  first f (x, y) = (f x, y)
extractRCArgs :: [String] -> ([String],[(String,String)])
 args =
  let (dargs,otherargs) = partition ("-D" `isPrefixOf`) args
  in (otherargs, map splitDefs (map (drop 2) dargs))
 where
  splitDefs darg = case break (== '=') darg of
    (var,_:val) -> (var,val)
    _           -> (darg,"")
updateRCDefs :: [(String,String)] -> [(String,String)] -> [(String,String)]
updateRCDefs orgdefs newdefs =
  map (\ (name,val) -> (name, maybe val id (lookup name newdefs))) orgdefs
 |