10.3.1.4. Opening and closing files {
aa) When, during transput, something happens which is left undefined, for example by explicitly calling undefined {a}, this does not imply that the elaboration is catastrophically and immediately interrupted {2.1.4.3.h }, but only that some sensible action is taken which is not or cannot be described by this Report alone and is generally implementation-dependent.
bb) A book is "linked" with a file by means of establish{b}, create{c}or open{d}. The linkage may be terminated by means of close {n}, lock {o}or scratch {p}.
cc) When a file is "established" on a channel, then a book is generated {5.2.3 } with a text of the given size, the given identification string, with putting set to true, and the logical end of the book at (1, 1, 1). An implementation may require {g}that the characters forming the identification string should be taken from a limited set and that the string should be limited in length, it may also prevent two books from having the same string, if the establishing is completed successfully, then the value 0 is returned; otherwise, some nonzero integer is returned (the value of this integer might indicate why the file was not established successfully). When a file is "created" on a channel, then a file is established with a book whose text has the default size for the channel and whose identification string is undefined.
dd) When a file is "opened", then the chain of backfiles is searched for the first book which is such that match {h}returns true. (The precise method of matching is not defined by this Report and will, in general, be implementation dependent. For example, the string supplied as parameter to open may include a password of some form.) If the end of the chain of backfiles is reached or if a book has been selected, but putting of the book yields true, or if putting to the book via the channel is possible and the book is already open, then the further elaboration is undefined. If the file is already open, an UP gremlins provides an opportunity for an appropriate system action on the book previously linked (in case no other copy of the file remains to preserve that linkage).
ee) The routine associate may be used to associate a file with a value of the mode specified by either REF [ ] CHAR, REF [ ] [ ] CHAR or REF [ ] [ ] [ ] CHAR, thus enabling such variables to be used as the book of a file,
ff) When a file is "closed", its book is attached to the chain of backfiles referenced by chainbfile. Some system-task is then activated by means of an UP gremlins. (This may reorganize the chain of backfiles, removing this book, or adding further copies of it. It may also cause the book to be output on some external device.)
gg) When a file is "locked", its book is attached to the chain of backfiles referenced by lockedbfile. Some system-task is then activated by means of an UP gremlins. A book which has been locked cannot be re-opened until some subsequent system-task has re-attached the book to the chain of backfiles available for opening.
hh) When a file is "scratched", some system-task is activated by means of an UP gremlins. (This may cause the book linked to the file to be disposed of in some manner.)}
PROC {?}undefined = INT: © some sensible system action yielding an integer to indicate what has been done; it is presumed that the system action may depend on a knowledge of any values accessible {2.1.2.c } inside the locale of any environ which is older than that in which this pseudo-comment is being elaborated {notwithstanding that no ALGOL 68 construct written here could access those values} ©;
PROC establish =
( REF FILE file, STRING idf, CHANNEL chan, INT p, l, c) INT:
BEGIN
DOWN bfileprotect;
©PRIM¢HEAP BOOK book :=
( ©PRIM¢HEAP FLEX [1 : p] FLEX [1 :l] FLEX [1: c] CHAR, (1, 1, 1), idf, TRUE, 1);
IF file available (chan) & (put OF chan) (book)
& estab OF chan & ~(POS (p, l, c) BEYOND max pos OF chan)
& ~(POS (1, 1, 1) BEYOND POS (p, l, c)) & idfok (idf)
THEN
( opened OF file | UP gremlins | UP bfileprotect);
file :=
( book, text OF book, chan, SKIP, SKIP,
¢ state: ¢ HEAP BOOL := FALSE, HEAP BOOL := TRUE,
HEAP BOOL := FALSE, HEAP BOOL := FALSE, HEAP BOOL := TRUE,
HEAP POS := (1, 1, 1), "", (standconv OF chan) (book),
¢ event routines: ¢ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
( REF FILE f, REF CHAR a) BOOL: FALSE);
( ~ bin possible (file) i | set char mood (file));
0
ELSE UP bfileprotect; undefined
FI
END;
PROC create = (REF FILE file, CHANNEL chan) INT:
BEGIN POS max pos = max pos OF chan;
establish (file, SKIP, chan, p OF max pos, l OF max pos, c OF max pos)
END;
PROC open = (REF FILE file, STRING idf, CHANNEL chan) INT:
BEGIN
DOWN bfileprotect;
IF file available (chan)
THEN REF REF BFILE bf := chainbfile; BOOL found := FALSE;
WHILE (REF BFILE (bf) :/=: NIL) & ~found
DO
IF match (idf, chan, book OF bf)
THEN found := TRUE
ELSE bf := next OF bf
FI
OD;
IF ~found
THEN UP bfileprotect; undefined
ELSE REF BOOK book := book OF bf;
IF putting OF book {|}OR (put OF chan) (book) & users OF book > 0
THEN
UP bfileprotect; undefined ¢ in this case opening is inhibited by other users -
the system may either wait, or yield nonzero (indicating unsuccessful opening) immediately ¢
ELSE
users OF book +:= 1;
( (put OF chan) (book) | putting OF book := TRUE );
REF REF BFILE (bf) := next OF bf; ¢ remove bfile from chain ¢
( opened OF file | UP gremlins | UP bfileprotect);
file :=
( book, text OF book, chan, SKIP, SKIP,
¢ state: ¢ HEAP BOOL := FALSE, HEAP BOOL := FALSE,
HEAP BOOL := FALSE, HEAP BOOL := FALSE,
HEAP BOOL := TRUE,
HEAP POS := (1, 1, 1), "", (standconv OF chan) (book),
¢ event routines: ¢ FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, (REF FILE f, REF CHAR a) BOOL: FALSE);
( ~ bin possible (file) | set char mood (file));
( ~ get possible (file) | set write mood (file));
( ~ put possible (file) | set read mood (file));
0
FI
FI
ELSE UP bfileprotect; undefined
FI
END;
PROC associate =
( REF FILE file, REF [ ][ ][ ] CHAR sss) VOID:
IF INT p = LWB sss; INT l = LWB sss [p]; INT c = LWB sss[p][l];
p = 1 & l = 1 & c = 1
THEN
PROC t = (REF BOOK a) BOOL: TRUE;
PROC f = (REF BOOK a) BOOL: FALSE;
CHANNEL chan = (t, t, t, t, f, f, f, BOOL: FALSE,
pos: (max int, max int, max int), SKIP, SKIP);
( opened OF file | DOWN bfileprotect; UP gremlins);
file :=
( HEAP BOOK := (SKIP, ( UPB sss + 1, 1, 1), SKIP, TRUE, 1), sss, chan,
SKIP, SKIP,
¢ state: ¢ HEAP BOOL := FALSE, HEAP BOOL := FALSE,
HEAP BOOL := TRUE, HEAP BOOL := FALSE, HEAP BOOL := TRUE,
HEAP POS := (1, 1, 1), "", SKIP,
¢ event routines: ¢ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
( REF FILE f, REF CHAR a) BOOL: FALSE)
ELSE undefined
FI;
f) PROC {?}file available = (CHANNEL chan)BOOL: © true if another file, at this instant of time, may be opened on 'chan' and false otherwise ©;
g) PROC {?}idf ok = (STRING idf)BOOL: © true if 'idf' is acceptable to the implementation as the identification of a new book and false otherwise ©;
h) PROC {?}match = (STRING idf, CHANNEL chan, REF BOOK book name)BOOL: © true if the book referred to by 'book name' may be identified by 'idf', and if the book may legitimately be accessed through 'chan', and false otherwise ©;
i) PROC {?}false = (REF FILE file)BOOL: FALSE # this is included for brevity in 'establish', 'open' and 'associate' #;
PROC {?} set write mood = (REF FILE f) VOID:
IF put possible (f) ¦
set possible (f) & bin mood OF f & read mood OF f
THEN undefined
ELSE REF BOOL (read mood OF f) := FALSE; REF BOOL (write mood OF f) := TRUE
FI;
k) PROC {?}set read mood = (REF FILE f)VOID: IF get possible(f)## set possible(f) bin mood OF f write mood OF f THEN undefined ELSE REF BOOL(read mood OF f) := TRUE; REF BOOL(write mood OF f) := FALSE FI;
l) PROC {?}set char mood = (REF FILE f)VOID: IF set possible(f) bin mood OF f THEN undefined ELSE REF BOOL(char mood OF f) := TRUE; REF BOOL(bin mood OF f) := FALSE FI;
m) PROC {?}set bin mood = (REF FILE f)VOID: IF bin possible(f) ¦ set possible(f) char mood OF f THEN undefined ELSE REF BOOL(char mood OF f):= FALSE; REF BOOL(bin mood OF f):= TRUE FI;
n) PROC close = (REF FILE file)VOID: IF opened OF file THEN DOWN bfileprotect; REF BOOL(opened OF file) := FALSE; REF BOOK book = book OF file; putting OF book := FALSE; users OF book -:= 1; (text OF file | (FLEXTEXT): chainbfile := ©PRIM#HEAP bfile := (book, chainbfile)); UP gremlins FI;
o) PROC lock (REF FILE file)VOID: IF opened OF file THEN DOWN bfileprotect; REF BOOL(opened OF file) := FALSE; REF BOOK book = book OF file; putting OF book := FALSE; users OF book -:= 1; (text OF file | (FLEXTEXT): lockedbfile := ©PRIM#HEAP bfile = (book, lockedbfile)); UP gremlins FI;
p) PROC scratch = (REF FILE file)VOID: IF opened OF
file THEN DOWN bfileprotect; REF BOOL(opened OF file) := FALSE; putting
OF book OF file := FALSE; users OF book OF file -:= 1; UP gremlins FI;
Next