Skip to content

Commit e69c72a

Browse files
committed
dev: include: revert wrong error position fix; refactor
Errors in the main file are being reported a few lines too high, due to the setOffset in includedirectivep. It seems reverting this should have restored the original bug with wrong line number in certain include error messages, but I can't find that right now.
1 parent 6521b8d commit e69c72a

File tree

1 file changed

+18
-22
lines changed

1 file changed

+18
-22
lines changed

hledger-lib/Hledger/Read/JournalReader.hs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -308,24 +308,24 @@ directivep = (do
308308
-- optionally with a file type prefix. Relative paths are relative to the current file.
309309
includedirectivep :: MonadIO m => ErroringJournalParser m ()
310310
includedirectivep = do
311-
-- save the position
312-
off <- getOffset
313-
pos <- getSourcePos
311+
-- save the position at start of include directive, for error messages
312+
eoff <- getOffset
313+
-- and the parent file's path, for error messages and debug output
314+
parentf <- getSourcePos >>= sourcePosFilePath
314315

315316
-- parse the directive
316317
string "include"
317318
lift skipNonNewlineSpaces1
318319
prefixedglob <- rstrip . T.unpack <$> takeWhileP Nothing (`notElem` [';','\n'])
319320
lift followingcommentp
320321
let (mprefix,glb) = splitReaderPrefix prefixedglob
321-
f <- sourcePosFilePath pos
322-
when (null $ dbg6 (f <> " include: glob pattern") glb) $
323-
customFailure $ parseErrorAt off $ "include needs a file path or glob pattern argument"
322+
when (null $ dbg6 (parentf <> " include: glob pattern") glb) $
323+
customFailure $ parseErrorAt eoff $ "include needs a file path or glob pattern argument"
324324

325325
-- Find the file or glob-matched files (just the ones from this include directive), with some IO error checking.
326326
-- Also report whether a glob pattern was used, and not just a literal file path.
327327
-- (paths, isglob) <- findMatchedFiles off pos glb
328-
paths <- findMatchedFiles off pos glb
328+
paths <- findMatchedFiles eoff parentf glb
329329

330330
-- XXX worth the trouble ? no
331331
-- Comprehensively exclude files already processed. Some complexities here:
@@ -343,9 +343,7 @@ includedirectivep = do
343343
Just fmt -> map ((show fmt++":")++) paths
344344

345345
-- Parse each one, as if inlined here.
346-
-- Reset the position to the `include` line, for error messages.
347-
setOffset off
348-
forM_ prefixedpaths $ parseIncludedFile off pos
346+
forM_ prefixedpaths $ parseIncludedFile eoff
349347

350348
where
351349

@@ -364,8 +362,8 @@ includedirectivep = do
364362
-- (detected with unsafePerformIO; it's not worth a ton of boilerplate).
365363
-- In that case, be aware ** recursive globs will search intermediate dot directories.
366364

367-
findMatchedFiles :: (MonadIO m) => Int -> SourcePos -> FilePath -> JournalParser m [FilePath]
368-
findMatchedFiles off pos globpattern = do
365+
findMatchedFiles :: (MonadIO m) => Int -> FilePath -> FilePath -> JournalParser m [FilePath]
366+
findMatchedFiles off parentf globpattern = do
369367

370368
-- Some notes about the Glob library that we use (related: https://github.com/Deewiant/glob/issues/49):
371369
-- It does not expand tilde.
@@ -385,8 +383,7 @@ includedirectivep = do
385383
expandedglob <- lift $ expandHomePath globpattern `orRethrowIOError` "failed to expand ~"
386384

387385
-- get the directory of the including file
388-
parentfile <- sourcePosFilePath pos
389-
let cwd = takeDirectory parentfile
386+
let cwd = takeDirectory parentf
390387

391388
-- Don't allow 3 or more stars.
392389
when ("***" `isInfixOf` expandedglob) $
@@ -436,23 +433,22 @@ includedirectivep = do
436433
-- If a glob was used, exclude the current file, for convenience.
437434
let
438435
files3 =
439-
dbg6 (parentfile <> " include: matched files" <> if isglob then " (excluding current file)" else "") $
440-
(if isglob then filter (/= parentfile) else id) files2
436+
dbg6 (parentf <> " include: matched files" <> if isglob then " (excluding current file)" else "") $
437+
(if isglob then filter (/= parentf) else id) files2
441438

442439
return files3
443440

444-
-- Parse the given included file (and any deeper includes, recursively)
445-
-- as if it was inlined in the current (parent) file.
446-
-- The position in the parent file is provided for error messages.
447-
parseIncludedFile :: MonadIO m => Int -> SourcePos -> PrefixedFilePath -> ErroringJournalParser m ()
448-
parseIncludedFile off _pos prefixedpath = do
441+
-- Parse the given included file (and any deeper includes, recursively) as if it was inlined in the current (parent) file.
442+
-- The offset of the start of the include directive in the parent file is provided for error messages.
443+
parseIncludedFile :: MonadIO m => Int -> PrefixedFilePath -> ErroringJournalParser m ()
444+
parseIncludedFile eoff prefixedpath = do
449445
let (_mprefix,filepath) = splitReaderPrefix prefixedpath
450446

451447
-- Throw an error if a cycle is detected
452448
parentj <- get
453449
let parentfilestack = jincludefilestack parentj
454450
when (dbg7 "parseIncludedFile: reading" filepath `elem` parentfilestack) $
455-
customFailure $ parseErrorAt off $ "This included file forms a cycle: " ++ filepath
451+
customFailure $ parseErrorAt eoff $ "This included file forms a cycle: " ++ filepath
456452

457453
-- Read the file's content, or throw an error
458454
childInput <- lift $ readFilePortably filepath `orRethrowIOError` "failed to read a file"

0 commit comments

Comments
 (0)