root/src/Pugs/Prim/FileTest.hs

Revision 17042, 3.8 kB (checked in by audreyt, 2 years 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 #-}
2module Pugs.Prim.FileTest (
3    isReadable, isWritable, isExecutable,
4    exists, isFile, isDirectory,
5    fileSize, sizeIsZero,
6    fileMTime, fileCTime, fileATime,
7    fileTestViaPerl5
8) where
9import Pugs.Internals
10import Pugs.Embed
11import Pugs.Types
12import 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
25isReadable   :: Val -> Eval Val
26isReadable   = fileTestIO fileTestIsReadable
27isWritable   :: Val -> Eval Val
28isWritable   = fileTestIO fileTestIsWritable
29isExecutable :: Val -> Eval Val
30isExecutable = fileTestIO fileTestIsExecutable
31exists       :: Val -> Eval Val
32exists       = fileTestIO fileTestExists
33isFile       :: Val -> Eval Val
34isFile       = fileTestIO fileTestIsFile
35isDirectory  :: Val -> Eval Val
36isDirectory  = fileTestIO fileTestIsDirectory
37fileSize     :: Val -> Eval Val
38fileSize     = fileTestIO fileTestFileSize
39sizeIsZero   :: Val -> Eval Val
40sizeIsZero   = fileTestIO fileTestSizeIsZero
41fileMTime    :: Val -> Eval Val
42fileMTime    = fileTime statFileMTime
43fileCTime    :: Val -> Eval Val
44fileCTime    = fileTime statFileCTime
45fileATime    :: Val -> Eval Val
46fileATime    = fileTime statFileATime
47
48fileTestViaPerl5 :: String -> Val -> Eval Val
49fileTestViaPerl5 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
61fileTime :: (FilePath -> IO Integer) -> Val -> Eval Val
62fileTime 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
69fileTestIO :: (Value n) => (n -> IO Val) -> Val -> Eval Val
70fileTestIO f v = do
71    str <- fromVal =<< fromVal' v
72    tryIO undef $ f str
73
74valFromBool :: Value a => a -> Bool -> Val
75valFromBool v b = if b then castV v else VBool False
76
77testPerms :: (Permissions -> Bool) -> FilePath -> IO Val
78testPerms t f = do
79    p <- getPermissions f
80    let b = t p
81    return $ valFromBool f b
82
83fileTestIsReadable :: FilePath -> IO Val
84fileTestIsReadable = testPerms readable
85
86fileTestIsWritable :: FilePath -> IO Val
87fileTestIsWritable = testPerms writable
88
89fileTestIsExecutable :: FilePath -> IO Val
90fileTestIsExecutable = testPerms $ liftM2 (||) executable searchable
91
92fileTestExists :: FilePath -> IO Val
93fileTestExists f = doesExist f >>= return . (valFromBool f)
94
95fileTestIsFile :: FilePath -> IO Val
96fileTestIsFile f = doesFileExist f >>= return . (valFromBool f)
97
98fileTestIsDirectory :: FilePath -> IO Val
99fileTestIsDirectory f = doesDirectoryExist f >>= return . (valFromBool f)
100
101fileTestFileSize :: FilePath -> IO Val
102fileTestFileSize f = statFileSize f >>= return . VInt
103
104fileTestSizeIsZero :: FilePath -> IO Val
105fileTestSizeIsZero f = do
106    n <- statFileSize f
107    return $ if n == 0 then VBool True else VBool False
108
109fileTestDo :: (FilePath -> IO Integer) -> FilePath -> IO Val
110fileTestDo test f = test f >>= return . VInt
Note: See TracBrowser for help on using the browser.