File: ReadFirst.hs

package info (click to toggle)
cpphs 0.7-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 360 kB
  • ctags: 18
  • sloc: haskell: 939; makefile: 79; sh: 36; ansic: 11
file content (62 lines) | stat: -rw-r--r-- 2,200 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
-----------------------------------------------------------------------------
-- |
-- Module      :  ReadFirst
-- Copyright   :  2004 Malcolm Wallace
-- Licence     :  LGPL
-- 
-- Maintainer  :  Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk>
-- Stability   :  experimental
-- Portability :  All
--
-- Read the first file that matches in a list of search paths.
-----------------------------------------------------------------------------

module ReadFirst
  ( readFirst
  ) where

import IO        (hPutStrLn, stderr)
import Directory (doesFileExist)
import List      (intersperse)
import Position  (Posn,directory)
import SymTab    (SymTab,lookupST)

-- | Attempt to read the given file from any location within the search path.
--   The first location found is returned, together with the file content.
--   (The directory of the calling file is always searched first, then
--    the current directory, finally any specified search path.)
readFirst :: String		-- ^ filename
	-> Posn			-- ^ inclusion point
	-> [String]		-- ^ search path
	-> SymTab String	-- ^ #defined symbols
	-> IO ( FilePath	-- ^ discovered file name, inc path
              , String		-- ^ file contents
              )

readFirst name demand path syms =
    try (cons dd (".":path))
  where
    dd = directory demand
    cons x xs = if null x then xs else x:xs
    realname = real name syms
    try [] = do
        hPutStrLn stderr ("Warning: Can't find file \""++realname
                         ++"\" in directories\n\t"
                         ++concat (intersperse "\n\t" (cons dd (".":path)))
                         ++"\n  Asked for by: "++show demand)
        return ("missing file: "++realname,"")
    try (p:ps) = do
        let file = p++'/':realname
        ok <- doesFileExist file
        if not ok then try ps
          else do content <- readFile file
                  return (file,content)

real :: String -> SymTab String -> String
real name syms = case name of
                   ('"':ns) -> init ns
                   ('<':ns) -> init ns
                   _        -> case lookupST name syms of
                                 Nothing -> name
                                 Just f  -> real f syms