Commit 6f020e62 authored by Bas Lijnse's avatar Bas Lijnse

Ported OSError and File modules to Mac

git-svn-id: https://svn.cs.ru.nl/repos/clean-platform/trunk@77 2afc29ad-3112-4e41-907a-9359c7e6e986
parent c57521f5
definition module _Posix
from _Pointer import :: Pointer
//Posix API calls
errno :: !*World -> (!Int,!*World)
strerr :: !Int -> Pointer
stat :: !{#Char} !{#Char} -> Int
unlink :: !{#Char} -> Int
implementation module _Posix
import _Pointer
errno :: !*World -> (!Int,!*World)
errno world = (getErrno,world)
where
getErrno :: Int
getErrno = readInt4S errnoAddr 0
errnoAddr :: Pointer
errnoAddr = code {
ccall __error ":p"
}
strerr :: !Int -> Pointer
strerr world = code {
ccall strerror "I:p"
}
stat :: !{#Char} !{#Char} -> !Int
stat path buf = code {
ccall stat "ss:I"
}
unlink :: !{#Char} -> !Int
unlink path = code {
ccall unlink "s:I"
}
definition module File
from StdFile import class FileSystem
from StdClass import class toString
import Error
import Void
import OSError
:: FileError = CannotOpen | CannotClose | IOError
instance toString FileError
/**
* Given a filename, reads the contents of the file to a String
* @param Path to the file to read
* @return contents of the file
*/
readFile :: !String *env -> (MaybeError String FileError, *env) | FileSystem env
/**
* Read all contents of a *File to a String.
* @precondition The file must be opened in read mode
* @param Path to the file to read
* @return contents of the file
*/
readAll :: *File -> (MaybeError String FileError, *File)
/**
* writes a string to a file
* @param Path to the file to read
* @param contents of the file
*/
writeFile :: !String !String *env -> (MaybeError Void FileError, *env) | FileSystem env
/**
* Performs a file operation on a given filename.
* The file is opened and closed by the withFile function.
* @param Path to the file
* @param file operation function
* @return file operation result
*/
withFile :: !String Int (*File -> (MaybeError a FileError,*File)) *env
-> (MaybeError a FileError, *env) | FileSystem env
/**
* checks if a file exists
* @param Path to the file
* @return file exists
*/
fileExists :: !String *World -> (Bool, *World)
/**
* deletes a file from disk
* @param Path to the file
* @return delete succeeded
*/
deleteFile :: !String *World -> (MaybeOSError Void, *World)
implementation module File
//StdEnv
import StdArray
import StdFile
import StdList
import StdString
import Error
import Void
import OSError
import _Pointer
from _Posix import qualified stat, unlink
CHUNK_SIZE :== 1024
instance toString FileError
where
toString CannotOpen = "Cannot open"
toString CannotClose = "Cannot close"
toString IOError = "I/O error"
readFile :: !String *env -> (MaybeError String FileError, *env) | FileSystem env
readFile filename env = withFile filename FReadData readAll env
readAll :: *File -> (MaybeError String FileError, *File)
readAll file
# (result, file) = readAcc file []
= case result of
Error e = (Error e, file)
Ok contents = (Ok ((foldr (+++) "" (reverse contents))), file)
where
readAcc :: *File [String] -> (MaybeError [String] FileError, *File)
readAcc file acc
# (str,file) = freads file CHUNK_SIZE
# (err,file) = ferror file
| err = (Error IOError,file)
# (eof,file) = fend file
| eof = (Ok [str:acc],file)
| otherwise = readAcc file [str:acc]
writeFile :: !String !String *env -> (MaybeError Void FileError, *env) | FileSystem env
writeFile filename contents env =
withFile filename FWriteData (\file -> (Ok Void, fwrites contents file)) env
withFile :: !String Int (*File -> (MaybeError a FileError,*File)) *env
-> (MaybeError a FileError, *env) | FileSystem env
withFile filename filemode operation env
# (ok,file,env) = fopen filename filemode env
| not ok = (Error CannotOpen, env)
# (result,file) = operation file
| isError result = (result, env)
# (ok,env) = fclose file env
| not ok = (Error CannotClose, env)
= (Ok (fromOk result), env)
fileExists :: !String *World -> (Bool, *World)
fileExists path world
# buf = createArray (IF_INT_64_OR_32 144 88) '\0'
# ok = '_Posix'.stat (packString path) buf
| ok == 0 = (True, world)
= (False, world)
deleteFile :: !String *World -> (MaybeOSError Void, *World)
deleteFile path world
# ok = '_Posix'.unlink (packString path)
| ok <> 0 = getLastOSError world
= (Ok Void, world)
definition module OSError
import Error
:: OSErrorCode :== Int
:: OSErrorMessage :== String
:: OSError :== (OSErrorCode, OSErrorMessage)
:: MaybeOSError a :== MaybeError a OSError
:: MaybeOSErrorCode a :== MaybeError a OSErrorCode
getLastOSError :: *World -> (MaybeOSError a, *World)
getLastOSErrorCode :: *World -> (MaybeOSErrorCode a, *World)
implementation module OSError
import Error, _Pointer
from _Posix import qualified errno, strerr
getLastOSError :: *World -> (MaybeOSError a, *World)
getLastOSError world
# (errno,world) = '_Posix'.errno world
= (Error (errno, message errno),world)
where
message :: !Int -> String
message errno
# ptr = '_Posix'.strerr errno
= derefString ptr
getLastOSErrorCode :: *World -> (MaybeOSErrorCode a, *World)
getLastOSErrorCode world
# (errno,world) = '_Posix'.errno world
= (Error errno, world)
......@@ -7,5 +7,8 @@ import Error
:: OSError :== (OSErrorCode, OSErrorMessage)
:: MaybeOSError a :== MaybeError a OSError
:: MaybeOSErrorCode a :== MaybeError a OSErrorCode
getLastOSError :: *World -> (MaybeOSError a, *World)
getLastOSErrorCode :: *World -> (MaybeOSErrorCode a, *World)
......@@ -39,4 +39,8 @@ formatMessage errorCode
# hMem = '_Windows'.localFree msgBuf.[0]
| hMem <> hMem = undef //Force eval of hMem
= message % (0, size message - 3) //Strip CR+LF
\ No newline at end of file
getLastOSErrorCode :: *World -> (MaybeOSErrorCode a, *World)
getLastOSErrorCode world
# (errorCode, world) = '_Windows'.getLastError world
= (Error errorCode, world)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment