summaryrefslogtreecommitdiff
path: root/ghc
diff options
context:
space:
mode:
authorAustin Seipp <austin@well-typed.com>2015-11-20 07:26:42 -0600
committerAustin Seipp <austin@well-typed.com>2015-11-20 07:27:05 -0600
commita689c8edb1639669cb8df58092b8b77a0a581717 (patch)
tree6b39f3fc3645e21ef5e40d96a38f76d2d9d033f0 /ghc
parentb72ca3e3fa54b80a2c376e259cd09df60c7106bf (diff)
downloadhaskell-a689c8edb1639669cb8df58092b8b77a0a581717.tar.gz
ghci: don't let ctags/etags overwrite source files
A ource file which was accidently passed as parameter into `:ctags` or `:etags` can be overwritten by tag data. This patch updates documentation to avoid confusion in commands usage and prevents `collateAndWriteTags` from modifying existing source files. Reviewed By: thomie, bgamari, austin Differential Revision: https://phabricator.haskell.org/D1471 GHC Trac Issues: #10989
Diffstat (limited to 'ghc')
-rw-r--r--ghc/GhciTags.hs16
-rw-r--r--ghc/InteractiveUI.hs6
2 files changed, 16 insertions, 6 deletions
diff --git a/ghc/GhciTags.hs b/ghc/GhciTags.hs
index b250637b07..fa94ea68fa 100644
--- a/ghc/GhciTags.hs
+++ b/ghc/GhciTags.hs
@@ -28,9 +28,11 @@ import MonadUtils
import Data.Function
import Data.Maybe
import Data.Ord
+import DriverPhases
import Panic
import Data.List
import Control.Monad
+import System.Directory
import System.IO
import System.IO.Error
@@ -131,23 +133,31 @@ tagInfo dflags unqual exported kind name loc
(showSDocForUser dflags unqual $ ftext (srcLocFile loc))
(srcLocLine loc) (srcLocCol loc) Nothing
+-- throw an exception when someone tries to overwrite existing source file (fix for #10989)
+writeTagsSafely :: FilePath -> String -> IO ()
+writeTagsSafely file str = do
+ dfe <- doesFileExist file
+ if dfe && isSourceFilename file
+ then throwGhcException (CmdLineError (file ++ " is existing source file. " ++
+ "Please specify another file name to store tags data"))
+ else writeFile file str
collateAndWriteTags :: TagsKind -> FilePath -> [TagInfo] -> IO (Either IOError ())
-- ctags style with the Ex exresion being just the line number, Vim et al
collateAndWriteTags CTagsWithLineNumbers file tagInfos = do
let tags = unlines $ sort $ map showCTag tagInfos
- tryIO (writeFile file tags)
+ tryIO (writeTagsSafely file tags)
-- ctags style with the Ex exresion being a regex searching the line, Vim et al
collateAndWriteTags CTagsWithRegExes file tagInfos = do -- ctags style, Vim et al
tagInfoGroups <- makeTagGroupsWithSrcInfo tagInfos
let tags = unlines $ sort $ map showCTag $concat tagInfoGroups
- tryIO (writeFile file tags)
+ tryIO (writeTagsSafely file tags)
collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
tagInfoGroups <- makeTagGroupsWithSrcInfo $filter tagExported tagInfos
let tagGroups = map processGroup tagInfoGroups
- tryIO (writeFile file $ concat tagGroups)
+ tryIO (writeTagsSafely file $ concat tagGroups)
where
processGroup [] = throwGhcException (CmdLineError "empty tag file group??")
diff --git a/ghc/InteractiveUI.hs b/ghc/InteractiveUI.hs
index 21eff8ff62..8f861eecac 100644
--- a/ghc/InteractiveUI.hs
+++ b/ghc/InteractiveUI.hs
@@ -244,13 +244,13 @@ defFullHelpText =
" :cd <dir> change directory to <dir>\n" ++
" :cmd <expr> run the commands returned by <expr>::IO String\n" ++
" :complete <dom> [<rng>] <s> list completions for partial input string\n" ++
- " :ctags[!] [<file>] create tags file for Vi (default: \"tags\")\n" ++
+ " :ctags[!] [<file>] create tags file <file> for Vi (default: \"tags\")\n" ++
" (!: use regex instead of line number)\n" ++
" :def <cmd> <expr> define command :<cmd> (later defined command has\n" ++
" precedence, ::<cmd> is always a builtin command)\n" ++
" :edit <file> edit file\n" ++
" :edit edit last module\n" ++
- " :etags [<file>] create tags file for Emacs (default: \"TAGS\")\n" ++
+ " :etags [<file>] create tags file <file> for Emacs (default: \"TAGS\")\n" ++
" :help, :? display this list of commands\n" ++
" :info[!] [<name> ...] display information about the given names\n" ++
" (!: do not filter instances)\n" ++
@@ -265,7 +265,7 @@ defFullHelpText =
" :reload[!] reload the current module set\n" ++
" (!: defer type errors)\n" ++
" :run function [<arguments> ...] run the function with the given arguments\n" ++
- " :script <filename> run the script <filename>\n" ++
+ " :script <file> run the script <file>\n" ++
" :type <expr> show the type of <expr>\n" ++
" :undef <cmd> undefine user-defined command :<cmd>\n" ++
" :!<command> run the shell command <command>\n" ++