File_Sys.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand        --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  is distributed  in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------


class FILE_SYS < $OPSYS_FILE_SYS

class FILE_SYS < $OPSYS_FILE_SYS is -- This class provides abstract file system operations using the -- underlying OS primitives. It provides an intermediate interface between -- the required library standard functionality and the underlying operating -- system, so that there is a common syntactic interface to the public -- routines defined in this class. -- This version is defined for Posix conformant unix implementations! -- Reference should be made to Posix specifications for further detail. -- Version 1.1 Apr 97. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 7 Nov 96 kh Original -- 5 Apr 97 kh Name changed and body filled out private const Raw_Read : CARD := UNICODE::LATIN_SMALL_LETTER_R.card ; private const Raw_Binary : CARD := UNICODE::LATIN_SMALL_LETTER_B.card ; private const Line_Max : CARD := 1023 ; -- unix max! private shared Mode_Names : ARRAY{STR} ; private check_modes is -- This routine is provided to read the mode name strings if this has -- not already been done. if void(Mode_Names) then Mode_Names := LIBCHARS::default.file_modes; end; end ; raw_open(name : STR) : REFERENCE pre (name.size > 0) post true is -- This routine attempts to open the named file and return the Operating -- System specific handle to the file. If unsuccessful then void is -- returned. mode : CODE_STR := CODE_STR::create(name.index_lib) + CHAR_CODE::create(Raw_Read,name.index_lib) + CHAR_CODE::create(Raw_Binary,name.index_lib) ; return OS_FILESYS::fopen(name.array_ptr,mode.tgt_str.array_ptr) end ; open(name : STR, mode : FILE_MODES) : REFERENCE pre (name.size > 0) and ~mode.is_nil post true is -- This routine attempts to open the named file and return the Operating -- System specific handle to the file. If unsuccessful then void is -- returned. check_modes ; return OS_FILESYS::fopen(name.array_ptr,Mode_Names[mode.card - 1].array_ptr) end ; create_file(name : STR, mode : FILE_MODES) : REFERENCE pre (name.size > 0) and ~mode.is_nil post true is -- This routine attempts to create the named file and return the -- Operating System specific handle to the file. If unsuccessful then -- void is returned. For this OS this is merely a wrapper for open! return open(name,mode) end ; rename_file(old_name : STR, new_name : STR ) : BOOL pre exists(old_name) and ~void(new_name) -- and its directory is writable! post true is -- This routine returns true if and only if the attempt to rename -- the file having the old name was successful. return OS_FILESYS::rename(old_name.array_ptr,new_name.array_ptr) = INT::zero end ; delete_file(name : STR ) : BOOL pre (name.size > 0) and exists(name) -- and directory is writable post ~exists(name) is -- This routine deletes the named file, returning true if and only if -- deletion has been successful. OS_FILESYS::unlink(name.array_ptr) ; return OS_FILESYS::access(name.array_ptr,0) /= INT::zero end ; create_tempfile : REFERENCE pre true post ~void(result) is -- This routine attempts to create a temporary file and return the -- Operating System specific handle to the file. If unsuccessful then -- void is returned. return OS_FILESYS::tmpfile end ; error(fyle : REFERENCE ) : BOOL is -- This predicate returns true if and only if the latest file operation -- resulted in an error. return FUDGE_FILESYS::fyle_error(fyle) end ; clearerr(fyle : REFERENCE) pre ~void(fyle) post true is -- This routine sets the error number to void for the indicated file. OS_FILESYS::fclearerr(fyle) end ; error_msg(fyle : REFERENCE ) : STR pre ~void(fyle) and error(fyle) post ~void(result) is -- This routine returns an operating system specific string error -- message using the current repertoire and encoding. This may or may not -- include the name by which the file is known. return STR::create_from_external_string(FUDGE_FILESYS::error_message) end ; close(fyle : REFERENCE) pre ~void(fyle) post true is -- This routine closes fyle in an operating system dependent manner. OS_FILESYS::fclose(fyle) end ; open_throw_back : REFERENCE pre true post ~void(result) is -- This routine attempts to set up the throwback mechanism for error -- reporting. If this is successfully done then the channel identity is -- returned, otherwise void. return void -- temporary fudge!! end ; throw(chan : REFERENCE, fyle_ident : STR, msg : STR, warn_only : BOOL ) pre ~void(fyle_ident) and ~void(msg) post true is -- This routine sends the throw-back messsage to the given channel in -- respect of the given file (identified by its OS dependent name). end ; close_throw_back(chan : REFERENCE) pre ~void(chan) post true is -- This routine closes the throwback channel in an operating system -- dependent manner. -- temporary fudge end ; exists(name : STR) : BOOL is -- This predicate returns true if and only if the named file/directory -- actually exists. return OS_FILESYS::access(name.array_ptr,0) = INT::zero end ; flush(fyle : REFERENCE) pre ~void(fyle) post true -- and buffers are empty is -- This routine flushes the file buffers as necessary, clearing input -- buffers and making sure that output buffers have been written out by -- the underlying operating system. OS_FILESYS::fflush(fyle) end ; flush(chan : REFERENCE, direction : FLUSH_CMDS ) pre ~void(chan) post true -- and buffers are empty is -- This routine flushes the buffers associated with chan in the direction -- specified. This is identical to the above in this implementation except -- for the standard input channel which requires a dummy read. if direction = FLUSH_CMDS::In_Buffer then dummy : FBINSTR := FBINSTR::create(Line_Max) ; loc_ref : REFERENCE := OS_FILESYS::fgets(dummy.array_ptr,Line_Max,STD_CHANS::stdin.chan) else OS_FILESYS::fflush(chan) end end ; size(fyle : REFERENCE, out size : CARD) : BOOL pre ~void(fyle) post true is -- This routine returns true if and only if it has been possible to -- determine the size of the given file - when the out parameter size is -- valid, otherwise false is returned and size is not valid. loc_current : INT := OS_FILESYS::ftell(fyle) ; if loc_current >= INT::zero then loc_res : INT := OS_FILESYS::fseek(fyle,INT::zero,(FILE_LOCS::End.card - 1)) ; if loc_res >= INT::zero then res : INT := OS_FILESYS::ftell(fyle) ; loc_res := OS_FILESYS::fseek(fyle,loc_current, (FILE_LOCS::Beginning.card - 1)) ; size := res.card ; return true else return false end else return false end end ; kind(code_val : CARD ) : FILE_KINDS pre true post void(result) or (result.card = code_val) is -- This routine provides the OS dependent mapping between the code -- value returned by some OS service and the portable class FILE_KINDS! return FILE_KINDS::create(code_val) end ; file_type(name : STR, leaf_name : STR ) : STR pre ~void(leaf_name) post true is -- This routine returns the string name of the file type as known to -- the operating system. sep : STR := name.index_lib.Kind_Separator.tgt_str ; loc_index : CARD := leaf_name.search_backwards(sep[0]) ; if loc_index.is_nil then return STR::create else return leaf_name.tail(leaf_name.size - (loc_index + sep.size)) end end ; set_type( full_name : STR, leaf_name : STR, new_type : STR) : STR pre ~void(leaf_name) and ~void(new_type) post (result.size >= leaf_name.size) is -- This routine sets the file type of the file (in the current directory) -- named full_name to have the required new type, returning the resultant -- leaf name (which may or may not be the same as leaf_name)! name_part : STR := leaf_name.head(leaf_name.size - 1 - file_type(full_name,leaf_name).size) ; if new_type.size > 0 then name_part := name_part + leaf_name.index_lib.Kind_Separator.tgt_str end ; return name_part + new_type end ; seek(fyle : REFERENCE, offset : INT, relative_to : FILE_LOCS ) : BOOL pre ~void(fyle) and ~void(relative_to) and (((relative_to = FILE_LOCS::Beginning) and (offset >= INT::zero)) or ((relative_to = FILE_LOCS::End) and (offset <= INT::zero)) or (relative_to = FILE_LOCS::Current)) post true is -- This routine returns true if and only if it has been possible to -- set the current file position to be offset relative to the given point, -- otherwise false. Note the dependency on the FILE_LOCS encoding!!! loc_res : INT := OS_FILESYS::fseek(fyle,offset,(relative_to.card - 1)) ; return loc_res >= INT::zero end ; position(fyle : REFERENCE ) : CARD pre ~void(fyle) post true is -- This routine returns the file index corresponding to the current -- position at which reading or writing will take place (in the absence of -- any intervening seek operation) loc_res : INT := OS_FILESYS::fseek(fyle,INT::zero,(FILE_LOCS::Current.card - 1)) ; if loc_res < INT::zero then return CARD::maxval else return loc_res.card end end ; putchar(item : OCTET, chan : REFERENCE ) : BOOL pre ~void(chan) post true is -- This routine may only be used for text output of a single character -- to the specified channel. OS_FILESYS::fputc(item,chan) ; return ~FUDGE_FILESYS::fyle_error(chan) end ; getchar(out item : OCTET, chan : REFERENCE ) : BOOL pre ~void(chan) post true is -- This routine may only be used for text input of a single octet -- 'character' from the specified channel. item := OS_FILESYS::fgetc(chan) ; return ~FUDGE_FILESYS::fyle_error(chan) end ; channel_read(cnt : CARD, chan : REFERENCE ) : FBINSTR pre ~void(chan) post true is -- This routine reads up to the given number of octets from the indicated -- channel into the buffer, returning true if successful. if cnt = 0 then return void else loc_buff : FBINSTR := FBINSTR::create(cnt) ; loc_ref : REFERENCE := OS_FILESYS::fgets(loc_buff.array_ptr,cnt,chan) ; if loc_ref.to_int < INT::zero then return void else length : CARD := SATHER_ENGINE::strlen(loc_ref) ; loc_buff.loc := length ; return loc_buff end end end ; file_read(buff : $FSTRINGS, size : CARD, inout cnt : CARD, fyle : REFERENCE) : BOOL pre ~void(buff) and (size > 0) and ~void(fyle) post (buff.loc = cnt) is -- "cnt" in the buffer -- This routine returns true if and only if it has been possible to read -- something from the file specified into the buffer provided. If successful -- then cnt is set to be the number of items read (NOT the number of bytes!). loc_res : INT := OS_FILESYS::fread(buff.array_ptr,size,cnt,fyle) ; if loc_res < INT::zero then return false else cnt := loc_res.card ; buff.loc := cnt ; return true end end ; file_read(buff : $FSTRINGS, size : CARD, inout cnt : CARD, offset : CARD, fyle : REFERENCE) : BOOL pre ~void(buff) and (size > 0) and ~void(fyle) and (buff.octets >= (cnt * size)) post (buff.loc = (cnt * size)) is -- "cnt" items in the buffer -- "offset" in the file! -- This routine returns true if and only if it has been possible to read -- something from the file specified into the buffer provided starting to -- read at the given fileoffset. If successful then cnt is set to be the -- number of items (NOT bytes) read. if ~seek(fyle,offset.int,FILE_LOCS::Beginning) then return false; end ; loc_res : INT := OS_FILESYS::fread(buff.array_ptr,size,cnt,fyle); if loc_res < INT::zero then return false else cnt := loc_res.card ; buff.loc := cnt ; return true end end ; file_write( buff : REFERENCE, size : CARD, inout cnt : CARD, fyle : REFERENCE) : BOOL pre ~void(buff) and (size > 0) and ~void(fyle) post ~result or (cnt = initial(cnt)) is -- "size" of the item to be written -- "cnt" No of items to write -- This routine returns true if and only if all of the specified output -- data (in the buffer) has been successfully written to the given file. The -- parameter cnt then indicates the number of items written ----- NOT the -- number of bytes. loc_res : INT := OS_FILESYS::fwrite(buff,size,cnt,fyle) ; if loc_res < INT::zero then return false else cnt := loc_res.card ; return true end end ; file_write( buff : $STRINGS, size : CARD, inout cnt : CARD, fyle : REFERENCE) : BOOL pre ~void(buff) and (size > 0) and ~void(fyle) post ~result or (cnt = initial(cnt)) is -- "size" of the item to be written -- "cnt" No of items to write -- This routine returns true if and only if all of the specified output -- data (in the buffer) has been successfully written to the given file, -- using the above routine. The parameter cnt then indicates the number of -- items written -- NOT the number of bytes - unless the size was 1!! return file_write(buff.array_ptr,size,inout cnt,fyle) end ; current_dir( path : STR ) : BOOL pre (path.size > 0) and exists(path) post true is -- This routine returns true if and only if it has been possible to -- change the current directory to the one named by path. return OS_FILESYS::chdir(path.array_ptr) = INT::zero end ; current_dir : STR pre true post void(result) or (result.size > 0) is -- This routine returns the string name of the current working directory -- in the current repertoire and encoding. If the operation fails then void -- is returned. loc_res : REFERENCE := FUDGE_FILESYS::get_cwd ; if void(loc_res) then return void else return STR::create_from_external_string(loc_res) end end ; make_dir( name : STR, access_code : ACCESS_SET ) : BOOL pre (name.size > 0) and ~exists(name) and ~access_code.is_empty post true is -- This routine returns true if and only if its attempt to create -- a directory with the given name and access permissions was successful. return OS_FILESYS::mkdir(name.array_ptr,CARD::create(access_code.binstr)) = INT::zero end ; delete_dir(name : STR) : BOOL pre (name.size > 0) and exists(name) post true is -- This routine returns true if and only if the attempt to delete -- the named directory was successful. return OS_FILESYS::rmdir(name.array_ptr) = INT::zero end ; open_dir( name : STR ) : REFERENCE pre (name.size > 0) and exists(name) post true is -- This routine returns the operating system provided handle for -- the directory object. If the attempt was unsuccessful then void -- is returned. res : INT := OS_FILESYS::opendir(name.array_ptr) ; if res = INT::zero then return void else return REFERENCE::create_from_value(res) end end ; close_dir( handle : REFERENCE ) : BOOL pre ~void(handle) post true is -- This routine returns true if and only if the attempt to close -- the indicated directory was successful. OS_FILESYS::closedir(handle) ; return true end ; rewind_dir(handle : REFERENCE, out offset : CARD): BOOL pre ~void(handle) post true is -- This routine returns true if and only if the attempt to rewind -- the indicated directory was successful. -- OS_FILESYS::fclearerr(handle) ; OS_FILESYS::rewinddir(handle) ; offset := 0 ; -- return ~FUDGE_FILESYS::fyle_error(handle) return true; end ; read_dir(handle : REFERENCE, inout offset : CARD) : STR pre ~void(handle) post void(result) or ((initial(offset) + 1) = offset) is -- This routine returns the string provided by the operating system -- if there is another sequential entry in the directory, otherwise void. loc_res : REFERENCE := FUDGE_FILESYS::read_dir(handle) ; if void(loc_res) then return void else offset := offset + 1 ; return STR::create_from_external_string(loc_res) end end ; rename_dir( old_name, new_name : STR) : BOOL pre ~void(old_name) and exists(old_name) and ~void(new_name) and ~exists(new_name) post true is -- This routine returns true if and only if the attempt to rename -- the directory having the old name was successful. return OS_FILESYS::rename(old_name.array_ptr,new_name.array_ptr) = INT::zero end ; get_label(name : STR, label : REFERENCE) : BOOL pre (name.size > 0) and exists(name) post true is -- This routine fills in the file label tuple and if this was possible -- then returns true, otherwise false and label is not set. return (OS_FILESYS::stat(name.array_ptr,label) = INT::zero) end ; set_times(name : STR, utime, mtime : TIME_STAMP) : BOOL pre (name.size > 0) and exists(name) -- and directory can be written to! post true is -- This routine attempts to set the update and access times for the -- named file, returning true if this was possible, otherwise false and no -- change has been effected. tim ::= TUP{TIME_STAMP,TIME_STAMP}::create(utime,mtime) ; tim_ref : REFERENCE := REFERENCE::create_from_object(tim) ; return OS_FILESYS::utime(name.array_ptr,tim_ref) = INT::zero end ; change_owner(name : STR, owner : USER, which : GROUP) : BOOL pre (name.size > 0) and exists(name) -- and directory can be written to! post true is -- This routine attempts to alter the owner and project group of the -- named file, returning true if successful , otherwise false and no change -- has been effected. return (OS_FILESYS::chown(name.array_ptr,owner.card,which.card) = INT::zero) end ; change_access(name : STR, access_mask : ACCESS_SET) : BOOL pre (name.size > 0) and exists(name) -- and directory can be written to! -- and ~void(access_mask) ! ACCESS_SET is immutable!! post true is -- This routine attempts to alter the access permissions for the named -- file. The mask should have an element CLEARED if that permission is to -- be allowed! return (OS_FILESYS::chmod(name.array_ptr,CARD::create(access_mask.binstr)) = INT::zero) end ; end ; -- FILE_SYS
external C class OS_FILESYS is -- This external class defines the interface to the underlying operating -- system services which are defined in the corresponding c file os_filesys. -- This version is defined for Posix conformant unix implementations! -- Reference should be made to Posix specifications for further detail. -- Version 1.0 Apr 97. Copyright K Hopper,U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 18 Apr 97 kh Original for portability. errno : CARD ; -- This returns an OS-dependent error code number. -- The following five routines are part of the Sather run-time -- engine and should normally only be used in that. fopen( name : REFERENCE, open_mode : REFERENCE) : REFERENCE ; -- This routine attempts to open the files named for the operations -- specified in the mode string. If void is returned the operation has -- failed, otherwise the OS-dependent file handle is returned. tmpfile : REFERENCE ; -- This routine creates a temporary file in an OS-dependent manner and -- returns the file handle to it. fclose(fyle : REFERENCE) ; -- This routine closes the file having the given handle. fseek(fyle : REFERENCE, offset : INT, relative_to : CARD) : INT ; -- This routine seeks to the given offset from the relative position -- indicated, returning the position relative to the beginning of the file -- if successful, otherwise -1. ftell(fyle : REFERENCE) : INT ; -- This routine returns the size of the file with the given handle -- in octets or -1 if it does not exist. fgets(buff : REFERENCE, size : CARD, chan : REFERENCE) : REFERENCE ; -- This routine fills buff with a string of up to size octets from the -- indicated channel returning the number of octets found or -1 if an error -- has occurred. fread(buff : REFERENCE, size, items : CARD, fyle : REFERENCE ) : INT ; -- This routine attempts to read size items into buff from the given -- file, returning the number read if successful or -1 if some error occurred. fwrite(buff : REFERENCE, size, items : CARD, fyle : REFERENCE ) : INT ; -- This routine attempts to write size items to the indicated file from -- the buffer, returning the number of octets written if successful, -- otherwise -1. fclearerr( fyle : REFERENCE) ; -- This routine clears the error status for the indicated file. fputc(oct : OCTET, fyle : REFERENCE) ; -- This routine puts a single octet into the indicated file. fgetc(fyle : REFERENCE) : OCTET ; -- This routine returns a single octet from the indicated file. fflush( fyle : REFERENCE) ; -- This routine flushes the OS buffer associated with the file -- indicated. If the file is currently being written to then the data will -- be sent to the file, otherwise the buffer will be emptied. setbuffer(fyle : REFERENCE, buff : REFERENCE, size : CARD) ; -- This routine sets buff (of the given size) for use by the operating -- system when reading/writing from/to the indicated file. mkdir(name : REFERENCE, permissions : CARD) : INT ; -- This routine attempts to create a directory with the given name and -- permissions (considered by the OS as a bit-set). rmdir(name : REFERENCE) : INT ; -- This routine attempts to delete the named directory, returning 0 -- if successul, chdir(name : REFERENCE) : INT ; -- This routine attempts to make the new current directory the one -- named, returning zero only if successful. opendir(name : REFERENCE) : INT ; -- This routine attempts to open the named directory, returning a handle -- to it. The directory is positioned at the first entry. If this fails -- then void is returned. closedir(handle : REFERENCE) ; -- This routine closes the indicated directory. rewinddir(handle : REFERENCE) ; -- This routine rewinds the indicated directory so that the next read -- will yield the first item (again). unlink(name : REFERENCE) ; -- This routine attempts to remove a file of the given name. tempnam(dir : REFERENCE, prefix : REFERENCE) : REFERENCE ; -- This routine attempts to return a name for the temporary file -- indicated (which has a leaf string prefixed as given) remove(name : REFERENCE) : INT ; -- This routine attempts to remove the named file from the filing system. rename( to, from : REFERENCE ) : INT ; -- This routine attempts to rename the file called to to be called from, -- returning zero if successful. access( name : REFERENCE, reason : CARD) : INT ; -- This routine determines whether or not the program has permission to -- carry out the indicated operation on the named file. Zero is returned -- if successful. utime(name : REFERENCE, file_times : REFERENCE) : INT ; -- This routine attempts to alter the modified and last accessed times -- of the named file to be the values given, returning zero if successful. ioctl(chan : INT, request : INT, arg : INT) : INT ; -- This routine is the standard Unix one for performing a wide variety -- of actions in respect of a device -- the given channel. The request code -- may indicate that the argument is not needed, some numeric code or even -- the address of some data structure. Zero is returned if the action is -- successful. stat(name : REFERENCE, tuple : REFERENCE) : INT ; -- This routine returns the file 'label' information or void if that -- is not available. chown(name : REFERENCE, owner : CARD, group : CARD) : INT ; -- This routine attempts to change the ownership of a file, returning -- zero if successful. chmod(name : REFERENCE, mode : CARD) : INT ; -- This routine attempts to set the permissions for a file (mode is -- actually an access-set mask), returning zero if successful. end ; -- OS_FILESYS
external C class FUDGE_FILESYS is -- This external class defines the interface to underlying operating -- system interface routines needed by this implementation. -- Version 1.0 Feb 99. Copyright K Hopper,U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 25 Feb 99 kh Original separated from OS_FILESYS fyle_error(fyle : REFERENCE) : BOOL ; -- This routine returns true if and only if an uncleared error has -- occurred when performing some action on the indicated file. error_message : REFERENCE ; -- This returns an OS-dependent message string corresponding to the -- most recently reported error. get_cwd : REFERENCE ; -- This routine returns a reference to an OS-provided buffer containing -- the string name of the current working directory. read_dir(handle : REFERENCE) : REFERENCE ; -- This routine attempts to read the name of an entry in the given -- directory, returning it as a C string, otherwise void! end ; -- FUDGE_FILESYS