StdFile.dcl 7.44 KB
Newer Older
1 2
system module StdFile

3 4 5 6
/**
 * Functions to manipulate the file system with the File type.
 */

7 8 9 10 11 12 13
// ****************************************************************************************
//	Concurrent Clean Standard Library Module Version 2.0
//	Copyright 1998 University of Nijmegen
// ****************************************************************************************

//	File modes synonyms

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
/**
 * File mode: read text
 * @type Int
 */
FReadText	:== 0

/**
 * File mode: write text
 * @type Int
 */
FWriteText	:== 1

/**
 * File mode: append text
 * @type Int
 */
FAppendText	:== 2

/**
 * File mode: read data
 * @type Int
 */
FReadData	:== 3

/**
 * File mode: write data
 * @type Int
 */
FWriteData	:== 4

/**
 * File mode: append data
 * @type Int
 */
FAppendData	:== 5
49 50 51

//	Seek modes synonyms

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
/**
 * Seek mode: the new position is the seek offset
 * @type Int
 */
FSeekSet	:== 0

/**
 * Seek mode: the new position is the current position plus the seek offset
 * @type Int
 */
FSeekCur	:== 1

/**
 * Seek mode: the new position is the size of the file plus the seek offset
 * @type Int
 */
FSeekEnd	:== 2

/**
 * The filesystem environment, independent from *World. This type can only be
 * used through the FileSystem and FileEnv classes.
 */
:: *Files

/**
 * Access to the filesystem.
 *
 * @var The unique type that is used to ensure purity.
 */
81
class FileSystem f where
82 83 84 85 86 87 88 89 90
	/**
	 * Opens a file for the first time in a certain mode.
	 * @param The filename
	 * @param The mode (read / write / append; text / data)
	 * @param The {{`FileSystem`}} (usually {{`World`}})
	 * @result A boolean indicating success
	 * @result The {{`File`}}
	 * @result The new {{`FileSystem`}}
	 */
91
	fopen :: !{#Char} !Int !*f -> (!Bool,!*File,!*f)
92 93 94 95 96 97 98 99

	/**
	 * Closes a file.
	 * @param The {{`File`}}
	 * @param The {{`FileSystem`}}
	 * @result A boolean indicating success
	 * @result The new {{`FileSystem`}}
	 */
100
	fclose :: !*File !*f -> (!Bool,!*f)
101 102 103 104

	/**
	 * Open the 'Console' for reading and writing.
	 */
105
	stdio  :: !*f -> (!*File,!*f)
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

	/**
	 * With `sfopen` a file can be opened for reading more than once. On a file
	 * opened by `sfopen` only the operations beginning with `sf` can be used.
	 * The `sf...` operations work just like the corresponding `f...`
	 * operations. They can't be used for files opened with {{`fopen`} or
	 * {{`freopen`}}.
	 *
	 * @param The filename
	 * @param The mode (read; text / data)
	 * @param The {{`FileSystem`}} (usually {{`World`}})
	 * @result A boolean indicating success
	 * @result The new {{`File`}}
	 * @result The new {{`FileSystem`}}
	 */
121 122 123 124 125
	sfopen :: !{#Char} !Int !*f -> (!Bool,!File,!*f)

instance FileSystem Files
instance FileSystem World

126 127 128 129 130
/**
 * An environment in which files can be dealt with.
 *
 * @var The unique type that is used to ensure purity.
 */
131 132 133 134 135 136
class FileEnv env where
	accFiles :: !.(*Files -> (.x,*Files)) !*env -> (!.x,!*env)
	appFiles :: !.(*Files -> *Files) !*env -> *env

instance FileEnv World

137 138 139 140 141 142 143 144
/**
 * Re-opens an open file in a possibly different mode.
 * @param The file
 * @param The new mode
 * @result A boolean indicating successful closing before reopening
 * @result The new file
 */
freopen :: !*File !Int -> (!Bool,!*File)
145 146 147

//	Reading from a File:

148 149 150 151 152
/**
 * Reads a character from a text file or a byte from a datafile.
 * @result A boolean indicating success
 * @result The read character
 */
153 154
freadc		:: !*File -> (!Bool,!Char,!*File)

155 156 157 158 159 160 161
/**
 * Reads an Integer from a textfile by skipping spaces, tabs and newlines and
 * then reading digits, which may be preceeded by a plus or minus sign.
 * From a datafile `freadi` will just read four bytes (a Clean Int).
 * @result A boolean indicating success
 * @result The read integer
 */
162 163
freadi		:: !*File -> (!Bool,!Int,!*File)

164 165 166 167 168 169 170
/**
 * Reads a Real from a textfile by skipping spaces, tabs and newlines and then
 * reading a character representation of a Real number.
 * From a datafile `freadr` will just read eight bytes (a Clean Real).
 * @result A boolean indicating success
 * @result The read real
 */
171 172
freadr		:: !*File -> (!Bool,!Real,!*File)

173 174 175 176 177 178 179 180 181
/**
 * Reads n characters from a text or data file, which are returned as a String.
 * If the file doesn't contain n characters the file will be read to the end
 * of the file. An empty String is returned if no characters can be read.
 * @param The file
 * @param The amount of characters to read
 * @result The read string
 * @result The file
 */
182 183
freads		:: ! *File !Int -> (!*{#Char},!*File)

184 185 186 187 188 189 190 191 192 193 194 195
/**
 * Reads `n` characters from a text or data file, which are returned in the
 * string `arg3` at positions `arg1`..`arg1+arg2-1`. If the file doesn't
 * contain `arg2` characters the file will be read to the end of the file, and
 * the part of the string `arg3` that could not be read will not be changed.
 *
 * @param The start of the substring to modify
 * @param The length of the substring
 * @param The string to modify
 * @result The number of characters read
 * @result The modified string
*/
196 197
freadsubstring :: !Int !Int !*{#Char} !*File -> (!Int,!*{#Char},!*File)

198 199 200 201
/**
 * Reads a line from a textfile, including a newline character, except for the
 * last line. `freadline` cannot be used on data files.
 */
202 203 204 205
freadline	:: !*File -> (!*{#Char},!*File)

//	Writing to a File:

206 207 208 209
/**
 * Writes a character to a textfile.
 * To a datafile fwritec writes one byte (a Clean Char).
 */
210 211
fwritec		:: !Char !*File -> *File

212 213 214 215
/**
 * Writes an Integer (its textual representation) to a text file. To a datafile
 * fwritei writes four bytes (a Clean Int).
 */
216 217
fwritei		:: !Int !*File -> *File

218 219 220 221
/**
 * Writes a Real (its textual representation) to a text file. To a datafile
 * fwriter writes eight bytes (a Clean Real).
 */
222 223
fwriter		:: !Real !*File -> *File

224 225 226
/**
 * Writes a String to a text or data file.
 */
227 228
fwrites		:: !{#Char} !*File -> *File

229 230 231 232
/**
 * Writes the characters at positions `arg1`..`arg1+arg2-1` of string `arg3` to
 * a text or data file.
 */
233 234
fwritesubstring :: !Int !Int !{#Char} !*File -> *File

235 236 237 238 239 240 241 242 243
/**
 * Overloaded write to file. This allows you to chain write operations, like:
 * `# f = f <<< "X is: " <<< x <<< "; y is: " <<< y <<< "\n"`
 *
 * @var The type that can be written to a file
 * @param The File
 * @param The thing to write
 * @result The new File
 */
244 245 246 247 248 249 250 251 252
class (<<<) infixl a :: !*File !a -> *File

instance <<< Int
instance <<< Char
instance <<< {#Char}
instance <<< Real

//	Testing:

253 254 255
/**
 * @result Whether end-of-file has been reached
 */
256 257
fend		:: !*File -> (!Bool,!*File)

258 259 260
/**
 * @result Whether an error has occurred during previous file I/O operations
 */
261 262
ferror		:: !*File -> (!Bool,!*File)

263 264 265 266
/**
 * @result The current position of the file pointer as an Integer. This
 *   position can be used later on for the fseek function.
 */
267 268
fposition	:: !*File -> (!Int,!*File)

269 270 271 272 273 274 275
/**
 * Move to a different position in the file
 *
 * @param The offset
 * @param A seek mode ({{`FSeekSet`}}, {{`FSeekCur`}} or {{`FSeekEnd`}})
 * @result True iff the seek was successful
 */
276 277 278 279
fseek		:: !*File !Int !Int -> (!Bool,!*File)

//	Predefined files.

280 281 282
/**
 * Open the 'Errors' file for writing only. May be opened more than once.
 */
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
stderr		:: *File

//	Opening and reading Shared Files:

sfreadc		:: !File -> (!Bool,!Char,!File)
sfreadi		:: !File -> (!Bool,!Int,!File)
sfreadr		:: !File -> (!Bool,!Real,!File)
sfreads		:: !File !Int -> (!*{#Char},!File)
sfreadline	:: !File -> (!*{#Char},!File)
sfseek		:: !File !Int !Int -> (!Bool,!File)

sfend		:: !File -> Bool
sfposition	:: !File -> Int

//	Convert a *File into:

299 300 301
/**
 * Change a file so that from now it can only be used with `sf...` operations.
 */
302
fshare		:: !*File -> File