root/src/Pugs/Prim/FileTest.hs

Revision 17042, 3.8 kB (checked in by audreyt, 10 months ago)

* Switch from System.Time to the newer Data.Time modules

for localtime(), time(), the :M filetest, etc.
(No user-visible changes.)

  • Property svn:mime-type set to text/plain; charset=UTF-8
  • Property svn:eol-style set to native
Line 
1 {-# OPTIONS_GHC -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances #-}
2 module Pugs.Prim.FileTest (
3     isReadable, isWritable, isExecutable,
4     exists, isFile, isDirectory,
5     fileSize, sizeIsZero,
6     fileMTime, fileCTime, fileATime,
7     fileTestViaPerl5
8 ) where
9 import Pugs.Internals
10 import Pugs.Embed
11 import Pugs.Types
12 import Pugs.AST hiding (isWritable)
13
14 -- filetest operators --
15
16 -- Officially, these should return a stat object, which sometimes pretends
17 -- to be a boolean, and may(?) return the filename in string context.
18 -- DARCS was working on stat, and we should perhaps grab their work:
19 --  http://www.abridgegame.org/pipermail/darcs-users/2005-February/005499.html
20 -- They currently (2004-04-05) seem to be using:
21 --  http://abridgegame.org/cgi-bin/darcs.cgi/darcs/win32/System/Posix.hs
22 -- For the moment, these return filename and false or undef.
23 -- Known Bugs: multiple stat()s are done, and filename isnt a boolean.
24
25 isReadable   :: Val -> Eval Val
26 isReadable   = fileTestIO fileTestIsReadable
27 isWritable   :: Val -> Eval Val
28 isWritable   = fileTestIO fileTestIsWritable
29 isExecutable :: Val -> Eval Val
30 isExecutable = fileTestIO fileTestIsExecutable
31 exists       :: Val -> Eval Val
32 exists       = fileTestIO fileTestExists
33 isFile       :: Val -> Eval Val
34 isFile       = fileTestIO fileTestIsFile
35 isDirectory  :: Val -> Eval Val
36 isDirectory  = fileTestIO fileTestIsDirectory
37 fileSize     :: Val -> Eval Val
38 fileSize     = fileTestIO fileTestFileSize
39 sizeIsZero   :: Val -> Eval Val
40 sizeIsZero   = fileTestIO fileTestSizeIsZero
41 fileMTime    :: Val -> Eval Val
42 fileMTime    = fileTime statFileMTime
43 fileCTime    :: Val -> Eval Val
44 fileCTime    = fileTime statFileCTime
45 fileATime    :: Val -> Eval Val
46 fileATime    = fileTime statFileATime
47
48 fileTestViaPerl5 :: String -> Val -> Eval Val
49 fileTestViaPerl5 testOp v = do
50     env     <- ask
51     envSV   <- io $ mkEnv env
52     argSV   <- fromVal v
53     subSV   <- io $ evalPerl5 ("sub { -" ++ testOp ++ " $_[0] }") envSV (enumCxt cxtItemAny)
54     rv      <- runInvokePerl5 subSV nullSV [argSV]
55     return $ case rv of
56         VStr "" -> VBool False
57         VNum 1  -> VBool True
58         VInt 1  -> VBool True
59         _       -> rv
60
61 fileTime :: (FilePath -> IO Integer) -> Val -> Eval Val
62 fileTime test f = do
63     t   <- fileTestIO (fileTestDo test) f
64     if (t == undef) then return VUndef else do
65     t'  <- fromVal t :: Eval Integer
66     b   <- fromVal =<< readVar (cast "$*BASETIME")
67     return $ VRat $ (b - (pugsTimeSpec . posixSecondsToUTCTime $ fromIntegral t')) / 86400
68
69 fileTestIO :: (Value n) => (n -> IO Val) -> Val -> Eval Val
70 fileTestIO f v = do
71     str <- fromVal =<< fromVal' v
72     tryIO undef $ f str
73
74 valFromBool :: Value a => a -> Bool -> Val
75 valFromBool v b = if b then castV v else VBool False
76
77 testPerms :: (Permissions -> Bool) -> FilePath -> IO Val
78 testPerms t f = do
79     p <- getPermissions f
80     let b = t p
81     return $ valFromBool f b
82
83 fileTestIsReadable :: FilePath -> IO Val
84 fileTestIsReadable = testPerms readable
85
86 fileTestIsWritable :: FilePath -> IO Val
87 fileTestIsWritable = testPerms writable
88
89 fileTestIsExecutable :: FilePath -> IO Val
90 fileTestIsExecutable = testPerms $ liftM2 (||) executable searchable
91
92 fileTestExists :: FilePath -> IO Val
93 fileTestExists f = doesExist f >>= return . (valFromBool f)
94
95 fileTestIsFile :: FilePath -> IO Val
96 fileTestIsFile f = doesFileExist f >>= return . (valFromBool f)
97
98 fileTestIsDirectory :: FilePath -> IO Val
99 fileTestIsDirectory f = doesDirectoryExist f >>= return . (valFromBool f)
100
101 fileTestFileSize :: FilePath -> IO Val
102 fileTestFileSize f = statFileSize f >>= return . VInt
103
104 fileTestSizeIsZero :: FilePath -> IO Val
105 fileTestSizeIsZero f = do
106     n <- statFileSize f
107     return $ if n == 0 then VBool True else VBool False
108
109 fileTestDo :: (FilePath -> IO Integer) -> FilePath -> IO Val
110 fileTestDo test f = test f >>= return . VInt
Note: See TracBrowser for help on using the browser.