lib: refactor low-level text file reading
This commit is contained in:
parent
631f0fc1e2
commit
81e964502b
@ -156,7 +156,7 @@ readJournalFile mformat mrulesfile assrt prefixedfile = do
|
|||||||
(mprefixformat, f) = splitReaderPrefix prefixedfile
|
(mprefixformat, f) = splitReaderPrefix prefixedfile
|
||||||
mfmt = mformat <|> mprefixformat
|
mfmt = mformat <|> mprefixformat
|
||||||
requireJournalFileExists f
|
requireJournalFileExists f
|
||||||
readFileOrStdinAnyLineEnding f >>= readJournal mfmt mrulesfile assrt (Just f)
|
readFileOrStdinPortably f >>= readJournal mfmt mrulesfile assrt (Just f)
|
||||||
|
|
||||||
-- | If a filepath is prefixed by one of the reader names and a colon,
|
-- | If a filepath is prefixed by one of the reader names and a colon,
|
||||||
-- split that off. Eg "csv:-" -> (Just "csv", "-").
|
-- split that off. Eg "csv:-" -> (Just "csv", "-").
|
||||||
@ -276,7 +276,7 @@ readJournalFileWithOpts iopts prefixedfile = do
|
|||||||
(mfmt, f) = splitReaderPrefix prefixedfile
|
(mfmt, f) = splitReaderPrefix prefixedfile
|
||||||
iopts' = iopts{mformat_=firstJust [mfmt, mformat_ iopts]}
|
iopts' = iopts{mformat_=firstJust [mfmt, mformat_ iopts]}
|
||||||
requireJournalFileExists f
|
requireJournalFileExists f
|
||||||
t <- readFileOrStdinAnyLineEnding f
|
t <- readFileOrStdinPortably f
|
||||||
ej <- readJournalWithOpts iopts' (Just f) t
|
ej <- readJournalWithOpts iopts' (Just f) t
|
||||||
case ej of
|
case ej of
|
||||||
Left e -> return $ Left e
|
Left e -> return $ Left e
|
||||||
@ -324,7 +324,7 @@ latestDatesFileFor f = dir </> ".latest" <.> fname
|
|||||||
(dir, fname) = splitFileName f
|
(dir, fname) = splitFileName f
|
||||||
|
|
||||||
readFileStrictly :: FilePath -> IO Text
|
readFileStrictly :: FilePath -> IO Text
|
||||||
readFileStrictly f = readFile' f >>= \t -> C.evaluate (T.length t) >> return t
|
readFileStrictly f = readFilePortably f >>= \t -> C.evaluate (T.length t) >> return t
|
||||||
|
|
||||||
-- | Given zero or more latest dates (all the same, representing the
|
-- | Given zero or more latest dates (all the same, representing the
|
||||||
-- latest previously seen transaction date, and how many transactions
|
-- latest previously seen transaction date, and how many transactions
|
||||||
|
|||||||
@ -104,7 +104,7 @@ readJournalFromCsv mrulesfile csvfile csvdata =
|
|||||||
if rulesfileexists
|
if rulesfileexists
|
||||||
then do
|
then do
|
||||||
dbg1IO "using conversion rules file" rulesfile
|
dbg1IO "using conversion rules file" rulesfile
|
||||||
liftIO $ (readFile' rulesfile >>= expandIncludes (takeDirectory rulesfile))
|
liftIO $ (readFilePortably rulesfile >>= expandIncludes (takeDirectory rulesfile))
|
||||||
else return $ defaultRulesText rulesfile
|
else return $ defaultRulesText rulesfile
|
||||||
rules <- liftIO (runExceptT $ parseAndValidateCsvRules rulesfile rulestext) >>= either throwerr return
|
rules <- liftIO (runExceptT $ parseAndValidateCsvRules rulesfile rulestext) >>= either throwerr return
|
||||||
dbg2IO "rules" rules
|
dbg2IO "rules" rules
|
||||||
@ -365,7 +365,7 @@ instance ShowErrorComponent String where
|
|||||||
-- and runs some extra validation checks.
|
-- and runs some extra validation checks.
|
||||||
parseRulesFile :: FilePath -> ExceptT String IO CsvRules
|
parseRulesFile :: FilePath -> ExceptT String IO CsvRules
|
||||||
parseRulesFile f =
|
parseRulesFile f =
|
||||||
liftIO (readFile' f >>= expandIncludes (takeDirectory f)) >>= parseAndValidateCsvRules f
|
liftIO (readFilePortably f >>= expandIncludes (takeDirectory f)) >>= parseAndValidateCsvRules f
|
||||||
|
|
||||||
-- | Inline all files referenced by include directives in this hledger CSV rules text, recursively.
|
-- | Inline all files referenced by include directives in this hledger CSV rules text, recursively.
|
||||||
-- Included file paths may be relative to the directory of the provided file path.
|
-- Included file paths may be relative to the directory of the provided file path.
|
||||||
|
|||||||
@ -188,7 +188,7 @@ includedirectivep = do
|
|||||||
liftIO $ runExceptT $ do
|
liftIO $ runExceptT $ do
|
||||||
let curdir = takeDirectory (sourceName parentpos)
|
let curdir = takeDirectory (sourceName parentpos)
|
||||||
filepath <- expandPath curdir filename `orRethrowIOError` (show parentpos ++ " locating " ++ filename)
|
filepath <- expandPath curdir filename `orRethrowIOError` (show parentpos ++ " locating " ++ filename)
|
||||||
txt <- readFileAnyLineEnding filepath `orRethrowIOError` (show parentpos ++ " reading " ++ filepath)
|
txt <- readFilePortably filepath `orRethrowIOError` (show parentpos ++ " reading " ++ filepath)
|
||||||
(ej1::Either (ParseError Char MPErr) ParsedJournal) <-
|
(ej1::Either (ParseError Char MPErr) ParsedJournal) <-
|
||||||
runParserT
|
runParserT
|
||||||
(evalStateT
|
(evalStateT
|
||||||
|
|||||||
@ -150,30 +150,23 @@ firstJust ms = case dropWhile (==Nothing) ms of
|
|||||||
[] -> Nothing
|
[] -> Nothing
|
||||||
(md:_) -> md
|
(md:_) -> md
|
||||||
|
|
||||||
-- | Read a file in universal newline mode, handling any of the usual line ending conventions.
|
-- | Read text from a file, handling any of the usual line ending conventions.
|
||||||
readFile' :: FilePath -> IO Text
|
readFilePortably :: FilePath -> IO Text
|
||||||
readFile' name = do
|
readFilePortably f = openFile f ReadMode >>= readHandlePortably
|
||||||
h <- openFile name ReadMode
|
|
||||||
hSetNewlineMode h universalNewlineMode
|
|
||||||
T.hGetContents h
|
|
||||||
|
|
||||||
-- | Read a file in universal newline mode, handling any of the usual line ending conventions.
|
-- | Read text from a file, or from standard input if the path is "-",
|
||||||
readFileAnyLineEnding :: FilePath -> IO Text
|
-- handling any of the usual line ending conventions.
|
||||||
readFileAnyLineEnding path = do
|
readFileOrStdinPortably :: String -> IO Text
|
||||||
h <- openFile path ReadMode
|
readFileOrStdinPortably f = openFileOrStdin f ReadMode >>= readHandlePortably
|
||||||
hSetNewlineMode h universalNewlineMode
|
|
||||||
T.hGetContents h
|
|
||||||
|
|
||||||
-- | Read the given file, or standard input if the path is "-", using
|
|
||||||
-- universal newline mode.
|
|
||||||
readFileOrStdinAnyLineEnding :: String -> IO Text
|
|
||||||
readFileOrStdinAnyLineEnding f = do
|
|
||||||
h <- fileHandle f
|
|
||||||
hSetNewlineMode h universalNewlineMode
|
|
||||||
T.hGetContents h
|
|
||||||
where
|
where
|
||||||
fileHandle "-" = return stdin
|
openFileOrStdin :: String -> IOMode -> IO Handle
|
||||||
fileHandle f = openFile f ReadMode
|
openFileOrStdin "-" _ = return stdin
|
||||||
|
openFileOrStdin f m = openFile f m
|
||||||
|
|
||||||
|
readHandlePortably :: Handle -> IO Text
|
||||||
|
readHandlePortably h = do
|
||||||
|
hSetNewlineMode h universalNewlineMode
|
||||||
|
T.hGetContents h
|
||||||
|
|
||||||
-- | Total version of maximum, for integral types, giving 0 for an empty list.
|
-- | Total version of maximum, for integral types, giving 0 for an empty list.
|
||||||
maximum' :: Integral a => [a] -> a
|
maximum' :: Integral a => [a] -> a
|
||||||
|
|||||||
@ -249,7 +249,7 @@ openBrowserOn u = trybrowsers browsers u
|
|||||||
-- indicating whether we did anything.
|
-- indicating whether we did anything.
|
||||||
writeFileWithBackupIfChanged :: FilePath -> T.Text -> IO Bool
|
writeFileWithBackupIfChanged :: FilePath -> T.Text -> IO Bool
|
||||||
writeFileWithBackupIfChanged f t = do
|
writeFileWithBackupIfChanged f t = do
|
||||||
s <- readFile' f
|
s <- readFilePortably f
|
||||||
if t == s then return False
|
if t == s then return False
|
||||||
else backUpFile f >> T.writeFile f t >> return True
|
else backUpFile f >> T.writeFile f t >> return True
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ writeFileWithBackup :: FilePath -> String -> IO ()
|
|||||||
writeFileWithBackup f t = backUpFile f >> writeFile f t
|
writeFileWithBackup f t = backUpFile f >> writeFile f t
|
||||||
|
|
||||||
readFileStrictly :: FilePath -> IO T.Text
|
readFileStrictly :: FilePath -> IO T.Text
|
||||||
readFileStrictly f = readFile' f >>= \s -> C.evaluate (T.length s) >> return s
|
readFileStrictly f = readFilePortably f >>= \s -> C.evaluate (T.length s) >> return s
|
||||||
|
|
||||||
-- | Back up this file with a (incrementing) numbered suffix, or give an error.
|
-- | Back up this file with a (incrementing) numbered suffix, or give an error.
|
||||||
backUpFile :: FilePath -> IO ()
|
backUpFile :: FilePath -> IO ()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user