Commit 67d6426e authored by Michael Hanus's avatar Michael Hanus
Browse files

RC file handling and option processing improved

parent d44376e8
*~
.cpm
.curry
src/REPL/PkgConfig.curry
......@@ -54,7 +54,7 @@ to check for errors and speed up later compilations
without re-compiling all imports.
If the module name is prefixed by a path, e.g., `dir1/dir2/Mod`,
then we change into the directory of the path (`dir1/dir2`)
then the REPL changes into the directory of the path (`dir1/dir2`)
and compile the main module there.
......@@ -78,6 +78,22 @@ Here are some examples of options and their values:
The actual options are specified by data of type `CCOption`
(see module `REPL.Compiler`).
RC file:
--------
The REPL reads on startup a compiler-specific configuration file
which contains definitions for some options and commands,
like a search path for additional libraries, commands to
show or edit source files, etc. A template for such a
configuration file is contained as `curryrc.default` in this package.
The REPL assumes that the home directory of the Curry compiler
contains a configuration file `CYCrc.default` if `CYC` is
the name of the compiler. If there is none, the configuration
file `curryrc.default` of this package is used.
On startup, the REPL copies this file (without the suffic `.default`)
into the user's home directory, if there is not already one, otherwise
the file is updated if the default file contains new fields.
Requirements for Curry Compilers used by CPM
============================================
......
############################################################################
# A standard configuration file for a Curry compiler used by the REPL.
#
# The syntax of this file is
#
# property=value\n
#
# Lines starting with '#' are comments.
#
############################################################################
# Default parameters that are always passed as initial parameters to the REPL
# (e.g., ":set +time :set +interactive :set fs")
defaultparams=
# Define path for searching modules in addition to standard libraries:
# (this path is placed in front of the standard library path)
libraries=
# Allow Curry extensions (currently: function patterns and records)
# (values: yes | no):
curryextensions=yes
# Show warnings for non-trivial overlapping rules (values: yes | no)
warnoverlapping=yes
# System command to edit the source file of a Curry program
# (if not defined, the value of the environment variable EDITOR is used)
editcommand=
# System command to show the source file of a Curry program
# (if not defined, the value of the environment variable PAGER is used)
showcommand=
# System command to view (Graphviz) dot graphs that come from stdin
# (e.g., used in CPM, Curry browser, erd2curry tools)
dotviewcommand=dot -Tpdf > /tmp/dotxxx.pdf && evince /tmp/dotxxx.pdf
# Optimize Boolean equalities (==): transform them into binding
# constraints (=:=) whenever they must be evaluated only to True.
# possible values:
# no (do not optimize)
# fast (optimize w.r.t. standard Prelude)
# full (perform full program analysis to optimize more occurrences)
bindingoptimization=fast
# Should the auxiliary files generated for the main goal be kept?
# (values: yes | no )
# Usually, they are deleted, i.e., "yes" might be useful for debugging
keepfiles=no
############################################################################
......@@ -18,6 +18,7 @@
"propertyfile" : ">=3.0.0, <4.0.0"
},
"exportedModules": [ "REPL.Main", "REPL.Compiler" ],
"configModule": "REPL.PkgConfig",
"source": {
"git": "https://git.ps.informatik.uni-kiel.de/curry-packages/curry-repl.git",
"tag": "$version"
......
......@@ -11,7 +11,7 @@ import Control.Monad ( when, unless )
import Curry.Compiler.Distribution ( installDir )
import Data.Char ( toLower, toUpper )
import Data.List ( intercalate, intersperse
, isInfixOf, isPrefixOf, nub, sort )
, isInfixOf, isPrefixOf, nub, partition, sort )
import System.Environment ( getArgs, getEnv )
import System.FilePath ( (</>), (<.>) )
import System.IO ( hClose, hFlush, hPutStrLn, isEOF, stdout )
......@@ -76,22 +76,23 @@ processArgsAndStart rst []
repLoop rst
processArgsAndStart rst (arg:args)
-- ignore empty arguments which can be provided by single or double quotes
| null arg = processArgsAndStart rst args
| null arg
= processArgsAndStart rst args
-- ignore '--nocypm' or '--noreadline'
-- (since they already processed by separate script to invoke the REPL)
| arg == "--nocypm" || arg == "--noreadline"
= processArgsAndStart rst args
| arg == "-h" || arg == "--help" || arg == "-?"
= printHelp >> cleanUpAndExitRepl rst
| arg == "-V" || arg == "--version"
= do putStrLn (ccBanner (compiler rst))
processArgsAndStart rst { quit = True} args
| arg == "--compiler-name"
= execCmp arg >> processArgsAndStart rst { quit = True} args
| arg == "--numeric-version"
= execCmp arg >> processArgsAndStart rst { quit = True} args
| arg == "--base-version"
= execCmp arg >> processArgsAndStart rst { quit = True} args
| arg == "-h" || arg == "--help" || arg == "-?"
= printHelp >> cleanUpAndExitRepl rst
| arg `elem` versionOpts -- process all version options and quit:
= do let (vopts,mopts) = partition (`elem` versionOpts) args
if null mopts
then do system $ unwords (ccExec (compiler rst) : arg : vopts)
cleanUpAndExitRepl rst
else writeErrorMsg ("illegal options: " ++ unwords mopts)
| isCommand arg = do
let (cmdargs, more) = break isCommand args
mbrst <- processCommand rst (tail (unwords (arg:cmdargs)))
......@@ -99,7 +100,7 @@ processArgsAndStart rst (arg:args)
| otherwise
= writeErrorMsg ("unknown command: " ++ unwords (arg:args)) >> printHelp
where
execCmp s = system $ unwords [ccExec (compiler rst), s]
versionOpts = ["--compiler-name", "--numeric-version", "--base-version"]
--- May a `String` be a REPL command?
isCommand :: String -> Bool
......
......@@ -19,11 +19,18 @@ import System.FilePath ( FilePath, (</>), (<.>) )
import System.Directory ( getHomeDirectory, doesFileExist, copyFile
, renameFile )
import REPL.Compiler
import REPL.PkgConfig ( packagePath )
import REPL.Utils ( strip )
--- The location of the default rc template.
defaultRC :: CCDescription -> FilePath
defaultRC cd = ccHome cd </> ccName cd ++ "rc.default"
--- Returns the location of the default rc template file.
--- If the Curry compiler has its own, return this one, otherwise
--- return the template from this package.
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")
--- Location of the rc file of a user.
--- After bootstrapping, one can also use Distribution.rcFileName
......@@ -38,14 +45,13 @@ rcFileName cd = (</> "." ++ ccName cd ++ "rc") `fmap` getHomeDirectory
readRC :: CCDescription -> IO [(String, String)]
readRC cd = do
rcname <- rcFileName cd
let rcdefname = defaultRC cd
rcdexists <- doesFileExist rcdefname
if rcdexists
then do
rcexists <- doesFileExist rcname
catch (if rcexists then updateRC cd else copyFile rcdefname rcname)
(const $ return ())
else putStrLn $ "Warning: file '" ++ rcdefname ++ "' not found!"
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]
......@@ -54,15 +60,15 @@ rcKeys = sort . map fst
--- Reads the rc file (which must be present) and compares the definitions
--- with the distribution rc file. If the set of variables is different,
--- update the rc file with the distribution but keep the user's definitions.
updateRC :: CCDescription -> IO ()
updateRC cd = do
updateRC :: CCDescription -> String -> IO ()
updateRC cd defaultrc = do
rcname <- rcFileName cd
userprops <- readPropertyFile rcname
distprops <- readPropertyFile (defaultRC cd)
distprops <- readPropertyFile defaultrc
unless (rcKeys userprops == rcKeys distprops) $ do
putStrLn $ "Updating \"" ++ rcname ++ "\"..."
putStrLn $ "Updating '" ++ rcname ++ "'..."
renameFile rcname $ rcname <.> "bak"
copyFile (defaultRC cd) rcname
copyFile defaultrc rcname
mapM_ (\ (n, v) -> maybe (return ())
(\uv -> unless (uv == v) $ updatePropertyFile rcname n uv)
(lookup n userprops))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment