lib: Re-implement 'includedirectivep' with the new 'ExceptT' layer
- Parse errors encountered in include files are treated as "final" parse errors in the parent file, preventing backtracking and fixing an issue in #853
This commit is contained in:
parent
3e54fc77a4
commit
31d4e930e7
@ -189,6 +189,7 @@ includedirectivep = do
|
|||||||
void newline
|
void newline
|
||||||
|
|
||||||
where
|
where
|
||||||
|
getFilePaths :: MonadIO m => SourcePos -> FilePath -> JournalParser m [FilePath]
|
||||||
getFilePaths parserpos filename = do
|
getFilePaths parserpos filename = do
|
||||||
curdir <- lift $ expandPath (takeDirectory $ sourceName parserpos) ""
|
curdir <- lift $ expandPath (takeDirectory $ sourceName parserpos) ""
|
||||||
`orRethrowIOError` (show parserpos ++ " locating " ++ filename)
|
`orRethrowIOError` (show parserpos ++ " locating " ++ filename)
|
||||||
@ -205,49 +206,41 @@ includedirectivep = do
|
|||||||
else customFailure $ parseErrorAt parserpos $
|
else customFailure $ parseErrorAt parserpos $
|
||||||
"No existing files match pattern: " ++ filename
|
"No existing files match pattern: " ++ filename
|
||||||
|
|
||||||
|
parseChild :: MonadIO m => SourcePos -> FilePath -> ErroringJournalParser m ()
|
||||||
parseChild parentpos filepath = do
|
parseChild parentpos filepath = do
|
||||||
parentfilestack <- fmap sourceName . statePos <$> getParserState
|
parentj <- get
|
||||||
when (filepath `elem` parentfilestack) $ customFailure $
|
|
||||||
parseErrorAt parentpos ("Cyclic include: " ++ filepath)
|
|
||||||
|
|
||||||
childInput <- lift $ readFilePortably filepath
|
let parentfilestack = jincludefilestack parentj
|
||||||
`orRethrowIOError` (show parentpos ++ " reading " ++ filepath)
|
when (filepath `elem` parentfilestack) $
|
||||||
|
fail ("Cyclic include: " ++ filepath)
|
||||||
|
|
||||||
-- save parent state
|
childInput <- lift $ readFilePortably filepath
|
||||||
parentParserState <- getParserState
|
`orRethrowIOError` (show parentpos ++ " reading " ++ filepath)
|
||||||
parentj <- get
|
let initChildj = newJournalWithParseStateFrom filepath parentj
|
||||||
|
|
||||||
let childj = newJournalWithParseStateFrom parentj
|
let parser = choiceInState
|
||||||
|
[ journalp
|
||||||
|
, timeclockfilep
|
||||||
|
, timedotfilep
|
||||||
|
] -- can't include a csv file yet, that reader is special
|
||||||
|
updatedChildj <- journalAddFile (filepath, childInput) <$>
|
||||||
|
parseIncludeFile parser initChildj filepath childInput
|
||||||
|
|
||||||
-- set child state
|
-- discard child's parse info, combine other fields
|
||||||
setInput childInput
|
put $ updatedChildj <> parentj
|
||||||
pushPosition $ initialPos filepath
|
|
||||||
put childj
|
|
||||||
|
|
||||||
-- parse include file
|
|
||||||
let parsers = [ journalp
|
|
||||||
, timeclockfilep
|
|
||||||
, timedotfilep
|
|
||||||
] -- can't include a csv file yet, that reader is special
|
|
||||||
updatedChildj <- journalAddFile (filepath, childInput) <$>
|
|
||||||
region (withSource childInput) (choiceInState parsers)
|
|
||||||
|
|
||||||
-- restore parent state, prepending the child's parse info
|
|
||||||
setParserState parentParserState
|
|
||||||
put $ updatedChildj <> parentj
|
|
||||||
-- discard child's parse info, prepend its (reversed) list data, combine other fields
|
|
||||||
|
|
||||||
|
|
||||||
newJournalWithParseStateFrom :: Journal -> Journal
|
newJournalWithParseStateFrom :: FilePath -> Journal -> Journal
|
||||||
newJournalWithParseStateFrom j = mempty{
|
newJournalWithParseStateFrom filepath j = mempty{
|
||||||
jparsedefaultyear = jparsedefaultyear j
|
jparsedefaultyear = jparsedefaultyear j
|
||||||
,jparsedefaultcommodity = jparsedefaultcommodity j
|
,jparsedefaultcommodity = jparsedefaultcommodity j
|
||||||
,jparseparentaccounts = jparseparentaccounts j
|
,jparseparentaccounts = jparseparentaccounts j
|
||||||
,jparsealiases = jparsealiases j
|
,jparsealiases = jparsealiases j
|
||||||
,jcommodities = jcommodities j
|
,jcommodities = jcommodities j
|
||||||
-- ,jparsetransactioncount = jparsetransactioncount j
|
-- ,jparsetransactioncount = jparsetransactioncount j
|
||||||
,jparsetimeclockentries = jparsetimeclockentries j
|
,jparsetimeclockentries = jparsetimeclockentries j
|
||||||
}
|
,jincludefilestack = filepath : jincludefilestack j
|
||||||
|
}
|
||||||
|
|
||||||
-- | Lift an IO action into the exception monad, rethrowing any IO
|
-- | Lift an IO action into the exception monad, rethrowing any IO
|
||||||
-- error with the given message prepended.
|
-- error with the given message prepended.
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user