@@ -15,6 +15,7 @@ import Idris.CmdOptions
15import Control.Monad.State.Strict
15import Control.Monad.State.Strict
16import Control.Applicative
16import Control.Applicative
17import System.FilePath (takeFileName, isValid)
17import System.FilePath (takeFileName, isValid)
18+import Data.Maybe (isNothing, fromJust)
19import Util.System
20import Util.System
@@ -79,18 +80,32 @@ filename = (do
79 -- Through at least version 0.9.19.1, IPKG executable values were
80 -- Through at least version 0.9.19.1, IPKG executable values were
80 -- possibly namespaced identifiers, like foo.bar.baz.
81 -- possibly namespaced identifiers, like foo.bar.baz.
81 show <$> fst <$> iName []
82 show <$> fst <$> iName []
82− if isValidFilename filename
83+ case filenameErrorMessage filename of
83− then return filename
84+ Just errorMessage -> fail errorMessage
84− else fail "a filename must be non-empty and have no directory component")
85+ Nothing -> return filename)
85 <?> "filename"
86 <?> "filename"
87− isValidFilename :: FilePath -> Bool
88+ -- TODO: Report failing span better! We could lookAhead,
88− isValidFilename path =
89+ -- or do something with DeltaParsing?
89− and [isNonEmpty, isValidPath, hasNoDirectoryComponent]
90+ filenameErrorMessage :: FilePath -> Maybe String
91+ filenameErrorMessage path = either Just (const Nothing) $ do
94+ checkNoDirectoryComponent path
91− isNonEmpty = path /= ""
96+ checkThat ok message =
97+ if ok then Right () else Left message
100+ checkThat (path /= "") "filename must not be empty"
92− isValidPath = System.FilePath.isValid path
103+ checkThat (System.FilePath.isValid path)
104+ "filename must contain only valid characters"
106+ checkNoDirectoryComponent path =
93− hasNoDirectoryComponent = path == takeFileName path
107+ checkThat (path == takeFileName path)
108+ "filename must contain no directory component"
96pClause :: PParser ()
111pClause :: PParser ()