@@ -15,6 +15,7 @@ import Idris.CmdOptions
1515import Control.Monad.State.Strict
1616import Control.Applicative
1717import System.FilePath (takeFileName, isValid)
18+import Data.Maybe (isNothing, fromJust)
1819
1920import Util.System
2021
@@ -79,18 +80,33 @@ filename = (do
7980 -- Through at least version 0.9.19.1, IPKG executable values were
8081 -- possibly namespaced identifiers, like foo.bar.baz.
8182 show <$> fst <$> iName []
82− if isValidFilename filename
83+ let errorMessage = filenameErrorMessage filename
84+ if isNothing errorMessage
8385 then return filename
84− else fail "a filename must be non-empty and have no directory component")
86+ else fail $ fromJust errorMessage)
8587 <?> "filename"
8688 where
87− isValidFilename :: FilePath -> Bool
88− isValidFilename path =
89− and [isNonEmpty, isValidPath, hasNoDirectoryComponent]
89+ -- TODO: Report failing span better! We could lookAhead,
90+ -- or do something with DeltaParsing?
91+ filenameErrorMessage :: FilePath -> Maybe String
92+ filenameErrorMessage path = either Just (const Nothing) $ do
93+ checkEmpty path
94+ checkValid path
95+ checkNoDirectoryComponent path
9096 where
91− isNonEmpty = path /= ""
92− isValidPath = System.FilePath.isValid path
93− hasNoDirectoryComponent = path == takeFileName path
97+ checkThat ok message =
98+ if ok then Right () else Left message
99+
100+ checkEmpty path =
101+ checkThat (path /= "") "filename must not be empty"
102+
103+ checkValid path =
104+ checkThat (System.FilePath.isValid path)
105+ "filename must contain only valid characters"
106+
107+ checkNoDirectoryComponent path =
108+ checkThat (path == takeFileName path)
109+ "filename must contain no directory component"
94110
95111
96112pClause :: PParser ()