-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathfile.tex
More file actions
1105 lines (875 loc) · 38.4 KB
/
Copy pathfile.tex
File metadata and controls
1105 lines (875 loc) · 38.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
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
49
50
51
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% !TeX root = forth.tex
% !TeX spellcheck = en_US
% !TeX program = pdflatex
\chapter{The optional File-Access word set} % 11
\wordlist{file}
\section{Introduction} % 11.1
These words provide access to mass storage in the form of ``files''
under the following assumptions:
\begin{itemize}
\item files are provided by a host operating system;
\item file names are represented as character strings;
\item the format of file names is determined by the host operating
system;
\item an open file is identified by a single-cell file identifier
(\emph{fileid});
\item file-state information (e.g., position, size) is managed by
the host operating system;
\item file contents are accessed as a sequence of characters;
\item file read operations return an actual transfer count, which
can differ from the requested transfer count.
\end{itemize}
\section{Additional terms} % 11.2
\begin{description}
\item[file-access method:]
A permissible means of accessing a file, such as ``read/write''
or ``read only''.
\item[file position:]
The character offset from the start of the file.
\item[input file:]
The file, containing a sequence of lines, that is the input source.
\end{description}
\section{Additional usage requirements} % 11.3
\subsection{Data types} % 11.3.1
Append table \ref{file:types} to table \ref{table:datatypes}.
\begin{table}[h]
\begin{center}
\caption{Data types}
\label{file:types}
\begin{tabular}{llr}
\hline\hline
\emph{Symbol} & \emph{Data type} & \emph{Size on stack} \\
\hline
\emph{fam} & file access method & 1 cell \\
\emph{fileid} & file identifier & 1 cell \\
\hline\hline
\end{tabular}
\end{center}
\end{table}
\subsubsection{File identifiers} % 11.3.1.1
File identifiers are implementation-dependent single-cell values
that are passed to file operators to designate specific files.
Opening a file assigns a file identifier, which remains valid
until closed.
\setcounter{subsubsection}{2}
\subsubsection{File access methods (11.3.1.3)} % 11.3.1.3
File access methods are implementation-defined single-cell
values.
\subsubsection{File names} % 11.3.1.4
\label{file:names}
A character string containing the name of the file. The file name
may include an implementation-dependent path name. The format of
file names is implementation defined.
\subsection{Blocks in files} % 11.3.2
\label{file:blocks}
Blocks may, but need not, reside in files.
When they do:
\begin{itemize}
\item Block numbers may be mapped to one or more files by
implementation-defined means. An ambiguous condition exists
if a requested block number is not currently mapped;
\item An \word[block]{UPDATE}d block that came from a file shall
be transferred back to the same file.
\end{itemize}
\subsection{Input source} % 11.3.4
\label{file:source}
The File-Access word set creates another input source for the text
interpreter. When the input source is a text file, \word[block]{BLK}
shall contain zero, \word{SOURCE-ID} shall contain the \emph{fileid}
of that text file, and the input buffer shall contain one line of
the text file. During text interpretation from a text file, the
value returned by \word{FILE-POSITION} for the \param{fileid} returned
by \word{SOURCE-ID} is undefined. A standard program
shall not call \word{REPOSITION-FILE} on the \param{fileid} returned
by \word{SOURCE-ID}.
Input with \word{INCLUDED}, \word{INCLUDE-FILE}, \word[block]{LOAD}
and \word[block]{EVALUATE} shall be nestable in any order to at least
eight levels.
A program that uses more than eight levels of input-file nesting has
an environmental dependency. See:
\xref[3.3.3.5 Input buffers]{usage:inbuf},
\xref[9. Optional Exception word set]{wordlist:exception}.
\subsection{Other transient regions} % 11.3.5
\label{file:buffers}
\subsection{Parsing} % 11.3.6
\label{file:parsing}
When parsing from a text file using a space delimiter, control
characters shall be treated the same as the space character.
Lines of at least 128 characters shall be supported. A program that
requires lines of more than 128 characters has an environmental
dependency.
A program may reposition the parse area within the input buffer by
manipulating the contents of \word[core]{toIN}. More extensive
repositioning can be accomplished using \word[core]{SAVE-INPUT} and
\word[core]{RESTORE-INPUT}.
See: \xref[3.4.1 Parsing]{usage:parsing}.
\section{Additional documentation requirements} % 11.4
\subsection{System documentation} % 11.4.1
\subsubsection{Implementation-defined options} % 11.4.1.1
\label{file:impopt}
\begin{itemize}
\item file access methods used by
\wref{file:BIN}{BIN},
\wref{file:CREATE-FILE}{CREATE-FILE}, \\
\wref{file:OPEN-FILE}{OPEN-FILE},
\wref{file:R/O}{R/O},
\wref{file:R/W}{R/W} and
\wref{file:W/O}{W/O};
\item file exceptions;
\item file line terminator (\wref{file:READ-LINE}{READ-LINE});
\item file name format (\xref[11.3.1.4 File names]{file:names});
\item information returned by \wref{file:FILE-STATUS}{FILE-STATUS};
\item input file state after an exception
(\wref{file:INCLUDE-FILE}{INCLUDE-FILE},
\wref{file:INCLUDED}{INCLUDED});
\item maximum depth of file input nesting
(\xref[11.3.4 Input source]{file:source});
\item maximum size of input line (\xref[11.3.6 Parsing]{file:parsing});
\item methods for mapping block ranges to files
(\xref[11.3.2 Blocks in files]{file:blocks});
\end{itemize}
\subsubsection{Ambiguous conditions} % 11.4.1.2
\begin{itemize}
\item attempting to position a file outside its boundaries
(\wref{file:REPOSITION-FILE}{REPOSITION-FILE});
\item attempting to read from file positions not yet written
(\wref{file:READ-FILE}{READ-FILE}, \\ \wref{file:READ-LINE}{READ-LINE});
\item \emph{fileid} is invalid (\wref{file:INCLUDE-FILE}{INCLUDE-FILE});
\item I/O exception reading or closing \emph{fileid}
(\wref{file:INCLUDE-FILE}{INCLUDE-FILE},
\wref{file:INCLUDED}{INCLUDED});
\item named file cannot be opened
(\wref{file:INCLUDED}{INCLUDED});
\item requesting an unmapped block number
(\xref[11.3.2 Blocks in files]{file:blocks});
\item using \wref{file:SOURCE-ID}{SOURCE-ID} when
\wref{block:BLK}{BLK} is not zero;
%
% ==== X:Required ====
%
\item a file is required while it is being \word{REQUIRED}
(\ref{file:REQUIRED}) or \word{INCLUDED} (\ref{file:INCLUDED});
\item a marker is defined outside and executed inside a file or
vice versa, and the file is \word{REQUIRED}
(\ref{file:REQUIRED}) again;
\item the same file is required twice using different names
(e.g., through symbolic links), or different files with the
same name are provided to \wref{file:REQUIRED}{REQUIRED} (by doing
some renaming between the invocations of \word{REQUIRED});
\item the stack effect of including with
\wref{file:REQUIRED}{REQUIRED} the file is not \stack{i*x}{i*x}.
\end{itemize}
\subsubsection{Other system documentation} % 11.4.1.3
\begin{itemize}
\item no additional requirements.
\end{itemize}
\subsection{Program documentation} % 11.4.2
\subsubsection{Environmental dependencies} % 11.4.2.1
\begin{itemize}
\item requiring lines longer than 128 characters
(\xref[11.3.6 Parsing]{file:parsing});
\item using more than eight levels of input-file nesting
(\xref[11.3.4 Input source]{file:source}).
\end{itemize}
\subsubsection{Other program documentation} % 11.4.2.2
\begin{itemize}
\item no additional requirements.
\end{itemize}
\section{Compliance and labeling} % 11.5
\subsection{Forth-\snapshot{} systems} % 11.5.1
The phrase ``Providing the File Access word set'' shall be appended
to the label of any Standard System that provides all of the File
Access word set.
The phrase ``Providing \emph{name(s)} from the File Access Extensions
word set'' shall be appended to the label of any Standard System that
provides portions of the File Access Extensions word set.
The phrase ``Providing the File Access Extensions word set'' shall
be appended to the label of any Standard System that provides all of
the File Access and File Access Extensions word sets.
\subsection{Forth-\snapshot{} programs} % 11.5.2
The phrase ``Requiring the File Access word set'' shall be appended
to the label of Standard Programs that require the system to provide
the File Access word set.
The phrase ``Requiring \emph{name(s)} from the File Access Extensions
word set'' shall be appended to the label of Standard Programs that
require the system to provide portions of the File Access Extensions
word set.
The phrase ``Requiring the File Access Extensions word set'' shall be
appended to the label of Standard Programs that require the system to
provide all of the File Access and File Access Extensions word sets.
\section{Glossary} % 11.6
\subsection{File Access words} % 11.6.1
\begin{worddef}[p]{0080}{(}[paren]
\item \stack{"ccc<paren>"}{}
Extend the semantics of \wref{core:p}{(} to include:
When parsing from a text file, if the end of the parse area is
reached before a right parenthesis is found, refill the input
buffer from the next line of the file, set \word[core]{toIN} to
zero, and resume parsing, repeating this process until either a
right parenthesis is found or the end of the file is reached.
\begin{testing} % T.11.6.1.0080 (
\test{\word{p} 1 2 3 \\
\tab[2.4] 4 5 6 \\
\tab[2.4] 7 8 9 ) 11 22 33}{11 22 33}
\end{testing}
\end{worddef}
\vspace*{-2ex}
\begin{worddef}{0765}{BIN}
\item \stack{fam_1}{fam_2}
Modify the implementation-defined file access method
\param{fam_1} to additionally select a \linebreak
``binary'', i.e., not line oriented, file access method,
giving access method \param{fam_2}.
\see \wref{file:R/O}{R/O},
\wref{file:R/W}{R/W},
\wref{file:W/O}{W/O},
\rref{file:BIN}{}.
\begin{rationale} % A.11.6.1.0765 BIN
Some operating systems require that files be opened in a
different mode to access their contents as an unstructured
stream of binary data rather than as a sequence of lines.
The arguments to \word{READ-FILE} and \word{WRITE-FILE} are
arrays of character storage elements, each element consisting
of at least 8 bits. The committee intends that, in
\word{BIN} mode, the contents of these storage elements can be
written to a file and later read back without alteration.
\end{rationale}
\end{worddef}
\vspace*{-2ex}
\begin{worddef}{0900}{CLOSE-FILE}
\item \stack{fileid}{ior}
Close the file identified by \param{fileid}. \param{ior} is the
implementation-defined I/O result code.
\end{worddef}
\vspace*{-2ex}
\begin{worddef}{1010}{CREATE-FILE}
\item \stack{c-addr u fam}{fileid ior}
Create the file named in the character string specified by
\param{c-addr} and \param{u}, and open it with file access method
\param{fam}. The meaning of values of \param{fam} is
implementation defined. If a file with the same name already
exists, recreate it as an empty file.
If the file was successfully created and opened, \param{ior} is
zero, \param{fileid} is its identifier, and the file has been
positioned to the start of the file.
Otherwise, \param{ior} is the implementation-defined I/O result
code and \param{fileid} is undefined.
\see \rref{file:CREATE-FILE}{}.
\begin{rationale} % A.11.6.1.1010 CREATE-FILE
Typical use:
\tab \word[core]{:} \texttt{X} {\ldots}
\word{Sq} \texttt{TEST.FTH"} \word{R/W}
\word{CREATE-FILE}
\word[core]{ABORTq} \texttt{CREATE-FILE FAILED"}
\word[core]{;}
\end{rationale}
\begin{testing} % T.11.6.1.1010 CREATE-FILE
\ttfamily
\word{:} fn1 \word{Sq} fatest1.txt" \word{;} \\
\word{VARIABLE} fid1
\test{fn1 \word{R/W} \word{CREATE-FILE} \word{SWAP} fid1 \word{!}}{0} \\
\test{fid1 \word{@} \word{CLOSE-FILE}}{0}
\end{testing}
\end{worddef}
\vspace*{-2ex}
\begin{worddef}{1190}{DELETE-FILE}
\item \stack{c-addr u}{ior}
Delete the file named in the character string specified by
\param{c-addr u}. \param{ior} is the {im\-ple\-ment\-ation-de\-fin\-ed}
I/O result code.
\begin{testing} % T.11.6.1.1190 DELETE-FILE
\test{fn2 \word{DELETE-FILE}}{0} \\
\test{fn2 \word{R/W} \word{BIN} \word{OPEN-FILE} \word{SWAP} \word{DROP}}{0} \\
\test{fn2 \word{DELETE-FILE}}{0}
\pagebreak
\end{testing}
\end{worddef}
\begin{worddef}{1520}{FILE-POSITION}
\item \stack{fileid}{ud ior}
\param{ud} is the current file position for the file identified
by \param{fileid}. \param{ior} is the implementation-defined I/O
result code. \param{ud} is undefined if \param{ior} is non-zero.
\end{worddef}
\begin{worddef}{1522}{FILE-SIZE}
\item \stack{fileid}{ud ior}
\param{ud} is the size, in characters, of the file identified by
\param{fileid}. \param{ior} is the {im\-ple\-ment\-ation-de\-fin\-ed} I/O
result code. This operation does not affect the value returned
by
\hyperref{}{file}{FILE-POSITION}{\textbf{\texttt{FILE-}}}
\hyperref{}{file}{FILE-POSITION}{\textbf{\texttt{POSITION}}}.
\param{ud} is undefined if \param{ior} is non-zero.
\begin{testing} % T.11.6.1.1522 FILE-SIZE
\ttfamily
\word{:} cbuf buf bsize 0 \word{FILL} \word{;} \\
\word{:} fn2 \word{Sq} fatest2.txt" \word{;} \\
\word{VARIABLE} fid2 \\
\word{:} setpad \word{PAD} 50 0 \word{DO} \word{I} \word{OVER} \word{C!} \word{CHAR+} \word{LOOP} \word{DROP} \word{;}
setpad
\textdf{\textbf{Note:} If anything else is defined
\texttt{setpad} must be called again as the pad may move}
\test{fn2 \word{R/W} \word{BIN} \word{CREATE-FILE} \word{SWAP} fid2 \word{!}}{0} \\
\test{\word{PAD} 50 fid2 \word{@} \word{WRITE-FILE} fid2 \word{@} \word{FLUSH-FILE}}{0 0} \\
\test{fid2 \word{@} \word{FILE-SIZE}}{50. 0} \\
\test{0. fid2 \word{@} \word{REPOSITION-FILE}}{0} \\
\test{cbuf buf 29 fid2 \word{@} \word{READ-FILE}}{29 0} \\
\test{\word{PAD} 29 buf 29 \word[string]{COMPARE}}{0} \\
\test{\word{PAD} 30 buf 30 \word[string]{COMPARE}}{1} \\
\test{cbuf buf 29 fid2 \word{@} \word{READ-FILE}}{21 0} \\
\test{\word{PAD} 29 \word{+} 21 buf 21 \word[string]{COMPARE}}{0} \\
\test{fid2 \word{@} \word{FILE-SIZE} \word{DROP} fid2 \word{@} \word{FILE-POSITION} \word{DROP} \word[double]{D=}}{<TRUE>} \\
\test{buf 10 fid2 \word{@} \word{READ-FILE}}{0 0} \\
\test{fid2 \word{@} \word{CLOSE-FILE}}{0}
\end{testing}
\end{worddef}
\begin{worddef}{1717}{INCLUDE-FILE}
\item \stack{i*x fileid}{j*x}
Remove \param{fileid} from the stack. Save the current input
source specification, including the current value of
\word{SOURCE-ID}. Store \param{fileid} in \word{SOURCE-ID}.
Make the file specified by \param{fileid} the input source. Store
zero in \word[block]{BLK}. Other stack effects are due to the
words included.
Repeat until end of file: read a line from the file, fill the
input buffer from the contents of that line, set \word[core]{toIN}
to zero, and interpret.
Text interpretation begins at the file position where the next
file read would occur.
When the end of the file is reached, close the file and restore
the input source specification to its saved value.
An ambiguous condition exists if \param{fileid} is invalid, if
there is an I/O exception reading \param{fileid}, or if an I/O
exception occurs while closing \param{fileid}. When an ambiguous
condition exists, the status (open or closed) of any files that
were being interpreted is {im\-ple\-ment\-ation-de\-fin\-ed}.
\see \xref[11.3.4 Input source]{file:source},
\rref{file:INCLUDE-FILE}{}.
\begin{rationale} % A.11.6.1.1717 INCLUDE-FILE
Here are two implementation alternatives for saving the input
source specification in the presence of text file input:
\begin{enumerate}
\item[1)] Save the file position (as returned by
\word{FILE-POSITION}) of the beginning of the line being
interpreted. To restore the input source specification,
seek to that position and re-read the line into the input
buffer.
\item[2)] Allocate a separate line buffer for each active text
input file, using that buffer as the input buffer. This
method avoids the ``seek and reread'' step, and allows the
use of ``pseudo-files'' such as pipes and other
sequential-access-only communication channels.
\end{enumerate}
\end{rationale}
\end{worddef}
\enlargethispage{-4ex}
\begin{worddef}{1718}{INCLUDED}
\item \stack{i*x c-addr u}{j*x}
Remove \param{c-addr u} from the stack. Save the current input
source specification, including the current value of
\word{SOURCE-ID}. Open the file specified by \param{c-addr u},
store the resulting \param{fileid} in \word{SOURCE-ID}, and make
it the input source. Store zero in \word[block]{BLK}. Other
stack effects are due to the words included.
Repeat until end of file: read a line from the file, fill the
input buffer from the contents of that line, set \word[core]{toIN}
to zero, and interpret.
Text interpretation begins at the start of the file.
When the end of the file is reached, close the file and restore
the input source specification to its saved value.
An ambiguous condition exists if the named file can not be
opened, if an I/O exception occurs reading the file, or if an
I/O exception occurs while closing the file. When an ambiguous
condition exists, the status (open or closed) of any files that
were being interpreted is implementation-defined.
\word{INCLUDED} may allocate memory in data space before it
starts interpreting the file.
\see \wref{file:INCLUDE-FILE}{INCLUDE-FILE},
\rref{file:INCLUDED}{}.
\begin{rationale} % A.11.6.1.1718 INCLUDED
Typical use:
{\ldots} \word{Sq} \texttt{filename"} \word{INCLUDED} {\ldots}
\end{rationale}
\begin{testing} % T.11.6.1.1718 INCLUDED
See \tref{file:REQUIRED}{REQUIRED}.
\end{testing}
\end{worddef}
\begin{worddef}{1970}{OPEN-FILE}
\item \stack{c-addr u fam}{fileid ior}
Open the file named in the character string specified by
\param{c-addr u}, with file access method indicated by
\param{fam}. The meaning of values of \param{fam} is
implementation defined.
If the file is successfully opened, \param{ior} is zero,
\param{fileid} is its identifier, and the file has been
positioned to the start of the file.
Otherwise, \param{ior} is the implementation-defined I/O
result code and \param{fileid} is undefined.
\see \rref{file:OPEN-FILE}{}.
\begin{rationale} % A.11.6.1.1970 OPEN-FILE
Typical use:
\tab \word[core]{:} \texttt{X} {\ldots}
\word{Sq} \texttt{ TEST.FTH"} \word{R/W}
\word{OPEN-FILE}~ \word[core]{ABORTq} \texttt{OPEN-FILE FAILED"}
{\ldots} \word[core]{;}
\end{rationale}
\end{worddef}
\begin{worddef}{2054}{R/O}[r-o]
\item \stack{}{fam}
\param{fam} is the implementation-defined value for selecting
the ``read only'' file access method.
\see \wref{file:CREATE-FILE}{CREATE-FILE},
\wref{file:OPEN-FILE}{OPEN-FILE}.
\end{worddef}
\begin{worddef}{2056}{R/W}[r-w]
\item \stack{}{fam}
\param{fam} is the implementation-defined value for selecting
the ``read/write'' file access method.
\see \wref{file:CREATE-FILE}{CREATE-FILE},
\wref{file:OPEN-FILE}{OPEN-FILE}.
\end{worddef}
\vspace*{-7ex}
\begin{worddef}{2080}{READ-FILE}
\item \stack{c-addr u_1 fileid}{u_2 ior}
Read \param{u_1} consecutive characters to \param{c-addr} from the
current position of the file identified by \param{fileid}.
If \param{u_1} characters are read without an exception, \param{ior}
is zero and \param{u_2} is equal to \param{u_1}.
If the end of the file is reached before \param{u_1} characters are
read, \param{ior} is zero and \param{u_2} is the number of characters
actually read.
If the operation is initiated when the value returned by
\word{FILE-POSITION} is equal to the value returned by
\word{FILE-SIZE} for the file identified by \param{fileid},
\param{ior} is zero and \param{u_2} is zero.
If an exception occurs, \param{ior} is the implementation-defined
I/O result code, and \param{u_2} is the number of characters
transferred to \param{c-addr} without an exception.
An ambiguous condition exists if the operation is initiated when
the value returned by \word{FILE-POSITION} is greater than the
value returned by \word{FILE-SIZE} for the file identified by
\param{fileid}, or if the requested operation attempts to read
portions of the file not written.
At the conclusion of the operation, \word{FILE-POSITION} returns
the next file position after the last character read.
\see \rref{file:READ-FILE}{}.
\begin{rationale} % A.11.6.1.2080 READ-FILE
A typical sequential file-processing algorithm might look like:
\begin{quote}\ttfamily\setwordlist{core}
\begin{tabbing}
\tab \= \hspace{12em} \= \kill
\word{BEGIN} \>\> \word{p} ) \\
\> {\ldots} \word[file]{READ-FILE} \word[exception]{THROW}
\> \word{p} length ) \\
\word{qDUP} \word{WHILE} \>\> \word{p} length ) \\
\> {\ldots} \> \word{p} ) \\
\word{REPEAT} \>\> \word{p} )
\end{tabbing}
\end{quote}\setwordlist{file}
In this example, \word[exception]{THROW} is used to handle
exception conditions, which are reported as
non-zero values of the \param{ior} return value from
\word{READ-FILE}. End-of-file is reported as a zero value of
the ``length'' return value.
\end{rationale}
\end{worddef}
\vspace*{-3ex}
\enlargethispage{8ex}
\begin{worddef}{2090}{READ-LINE}
\item \stack{c-addr u_1 fileid}{u_2 flag ior}
Read the next line from the file specified by \param{fileid} into
memory at the address \param{c-addr}. At most \param{u_1} characters
are read. Up to two implementation-defined line-terminating
characters may be read into memory at the end of the line, but
are not included in the count \param{u_2}. The line buffer provided
by \param{c-addr} should be at least \param{u_1+2} characters long.
If the operation succeeded, \param{flag} is true and \param{ior}
is zero. If a line terminator was received before \param{u_1}
characters were read, then \param{u_2} is the number of characters,
not including the line terminator, actually read ($0 <=$ \param{u_2}
$<=$ \param{u_1}). When \param{u_1} = \param{u_2} the line
terminator has yet to be reached.
If the operation is initiated when the value returned by
\word{FILE-POSITION} is equal to the value returned by
\word{FILE-SIZE} for the file identified by \param{fileid},
\param{flag} is false, \param{ior} is zero, and \param{u_2} is zero.
If \param{ior} is non-zero, an exception occurred during the
operation and \param{ior} is the implementation-defined I/O
result code.
An ambiguous condition exists if the operation is initiated when
the value returned by \word{FILE-POSITION} is greater than the
value returned by \word{FILE-SIZE} for the file identified by
\param{fileid}, or if the requested operation attempts to read
portions of the file not written.
At the conclusion of the operation, \word{FILE-POSITION} returns
the next file position after the last character read.
\see \rref{file:READ-LINE}{}.
\begin{rationale} % A.11.6.1.2090 READ-LINE
Implementations are allowed to store the line terminator in
the memory buffer in order to allow the use of line reading
functions provided by host operating systems, some of which
store the terminator. Without this provision, a transient
buffer might be needed. The two-character limitation is
sufficient for the vast majority of existing operating
systems. Implementations on host operating systems whose line
terminator sequence is longer than two characters may have to
take special action to prevent the storage of more than two
terminator characters.
Standard Programs may not depend on the presence of any such
terminator sequence in the buffer.
A typical line-oriented sequential file-processing algorithm
might look like:
\begin{quote}\ttfamily\setwordlist{core}
\begin{tabbing}
\tab \= \hspace{12em} \= \kill
\word{BEGIN} \>\> \word{p} ) \\
\> {\ldots} \word[file]{READ-LINE} \word[exception]{THROW}
\> \word{p} length not-eof-flag ) \\
\word{WHILE} \>\> \word{p} length ) \\
\> {\ldots} \> \word{p} ) \\
\word{REPEAT} \word{DROP} \>\> \word{p} ) \\
\end{tabbing}
\end{quote}\setwordlist{file}
\word{READ-LINE} needs a separate end-of-file flag because
empty (zero-length) lines are a routine occurrence, so a
zero-length line cannot be used to signify end-of-file.
\end{rationale}
\begin{testing} % T.11.6.1.2090 READ-LINE
\ttfamily
200 \word{CONSTANT} bsize \\
\word{CREATE} buf bsize \word{ALLOT} \\
\word{VARIABLE} \#chars
\test{fn1 \word{R/O} \word{OPEN-FILE} \word{SWAP} fid1 \word{!}}{0} \\
\test{fid1 \word{@} \word{FILE-POSITION}}{0. 0} \\
\test{buf 100 fid1 \word{@} \word{READ-LINE} \word{ROT} \word{DUP} \#chars \word{!}}{\\
\tab[1.2] <TRUE> 0 line1 \word{SWAP} \word{DROP}} \\
\test{buf \#chars \word{@} line1 \word[string]{COMPARE}}{0} \\
\test{fid1 \word{@} \word{CLOSE-FILE}}{0}
\end{testing}
\end{worddef}
\begin{worddef}{2142}{REPOSITION-FILE}
\item \stack{ud fileid}{ior}
Reposition the file identified by \param{fileid} to \param{ud}.
\param{ior} is the implementation-defined I/O result code. An
ambiguous condition exists if the file is positioned outside
the file boundaries.
At the conclusion of the operation, \word{FILE-POSITION}
returns the value \param{ud}.
\begin{testing} % T.11.6.1.2142 REPOSITION-FILE
\ttfamily
\word{:} line2 \word{Sq} Line 2 blah blah blah" \word{;} \\
\word{:} rl1 buf 100 fid1 \word{@} \word{READ-LINE} \word{;} \\
\word[double]{2VARIABLE} fp
\test{fn1 \word{R/W} \word{OPEN-FILE} \word{SWAP} fid1 \word{!}}{0} \\
\test{fid1 \word{@} \word{FILE-SIZE} \word{DROP} fid1 \word{@} \word{REPOSITION-FILE}}{0} \\
\test{fid1 \word{@} \word{FILE-SIZE}}{fid1 \word{@} \word{FILE-POSITION}}
\test{line2 fid1 \word{@} \word{WRITE-FILE}}{0} \\
\test{10. fid1 \word{@} \word{REPOSITION-FILE}}{0} \\
\test{fid1 \word{@} \word{FILE-POSITION}}{10. 0}
\test{0. fid1 \word{@} \word{REPOSITION-FILE}}{0} \\
\test{rl1}{line1 \word{SWAP} \word{DROP} <TRUE> 0} \\
\test{rl1}{\word{ROT} \word{DUP} \#chars \word{!}}{<TRUE> 0 line2 \word{SWAP} \word{DROP}} \\
\test{buf \#chars \word{@} line2 \word[string]{COMPARE}}{0} \\
\test{rl1}{0 <FALSE> 0}
\test{fid1 \word{@} \word{FILE-POSITION} \word{ROT} \word{ROT} fp \word{2!}}{0} \\
\test{fp \word{2@} fid1 \word{@} \word{FILE-SIZE} \word{DROP} \word[double]{D=}}{<TRUE>} \\
\test{\word{Sq} " fid1 \word{@} \word{WRITE-LINE}}{0} \\
\test{\word{Sq} " fid1 \word{@} \word{WRITE-LINE}}{0} \\
\test{fp \word{2@} fid1 \word{@} \word{REPOSITION-FILE}}{0} \\
\test{rl1}{0 <TRUE> 0} \\
\test{rl1}{0 <TRUE> 0} \\
\test{rl1}{0 <FALSE> 0} \\
\test{fid1 \word{@} \word{CLOSE-FILE}}{0}
\end{testing}
\end{worddef}
\begin{worddef}{2147}{RESIZE-FILE}
\item \stack{ud fileid}{ior}
Set the size of the file identified by \param{fileid} to
\param{ud}. \param{ior} is the implementation-defined I/O result
code.
If the resultant file is larger than the file before the
operation, the portion of the file added as a result of the
operation might not have been written.
At the conclusion of the operation, \word{FILE-SIZE} returns
the value \param{ud} and
\hyperref{}{file}{FILE-POSITION}{\textbf{\texttt{FILE-}}} \linebreak
\hyperref{}{file}{FILE-POSITION}{\textbf{\texttt{POSITION}}}
returns an unspecified value.
\see \wref{file:READ-FILE}{READ-FILE},
\wref{file:READ-LINE}{READ-LINE}.
\begin{testing} % T.11.6.1.2147 RESIZE-FILE
\texttt{setpad} \\
\test{fn2 \word{R/W} \word{BIN} \word{OPEN-FILE} \word{SWAP} fid2 \word{!}}{0} \\
\test{37. fid2 \word{@} \word{RESIZE-FILE}}{0} \\
\test{fid2 \word{@} \word{FILE-SIZE}}{37. 0} \\
\test{0. fid2 \word{@} \word{REPOSITION-FILE}}{0} \\
\test{cbuf buf 100 fid2 \word{@} \word{READ-FILE}}{37 0} \\
\test{\word{PAD} 37 buf 37 \word[string]{COMPARE}}{0} \\
\test{\word{PAD} 38 buf 38 \word[string]{COMPARE}}{1} \\
\test{500. fid2 \word{@} \word{RESIZE-FILE}}{0} \\
\test{fid2 \word{@} \word{FILE-SIZE}}{500. 0} \\
\test{0. fid2 \word{@} \word{REPOSITION-FILE}}{0} \\
\test{cbuf buf 100 fid2 \word{@} \word{READ-FILE}}{100 0} \\
\test{\word{PAD} 37 buf 37 \word[string]{COMPARE}}{0} \\
\test{fid2 \word{@} \word{CLOSE-FILE}}{0}
\end{testing}
\end{worddef}
\begin{worddef}{2218}{SOURCE-ID}[source-i-d]
\item \stack{}{0 | -1 | fileid}
Extend \wref{core:SOURCE-ID}{SOURCE-ID} to include text-file
input as follows:
\begin{center}
\begin{tabular}{cl}
\hline\hline
\word{SOURCE-ID} & Input source \\
\hline
\emph{fileid} & Text file ``\emph{fileid}'' \\
\emph{-1} & String (via \word[core]{EVALUATE}) \\
\emph{0} & User input device \\
\hline\hline
\end{tabular}
\end{center}
An ambiguous condition exists if \word{SOURCE-ID} is used when
\word[block]{BLK} contains a non-zero value.
\begin{testing} % T.11.6.1.2218 SOURCE-ID
\test{\word{SOURCE-ID} \word{DUP} -1 \word{=} \word{SWAP} \word{0=} \word{OR}}{<FALSE>}
\end{testing}
\end{worddef}
\begin{worddef}{2425}{W/O}[w-o]
\item \stack{}{fam}
\param{fam} is the implementation-defined value for selecting
the ``write only'' file access method.
\see \wref{file:CREATE-FILE}{CREATE-FILE},
\wref{file:OPEN-FILE}{OPEN-FILE}.
\end{worddef}
\vspace*{-4ex}
\begin{worddef}{2480}{WRITE-FILE}
\item \stack{c-addr u fileid}{ior}
Write \param{u} characters from \param{c-addr} to the file
identified by \param{fileid} starting at its current position.
\param{ior} is the implementation-defined I/O result code.
At the conclusion of the operation, \word{FILE-POSITION} returns
the next file position after the last character written to the
file, and \word{FILE-SIZE} returns a value greater than or equal
to the value returned by \word{FILE-POSITION}.
\see \wref{file:READ-FILE}{READ-FILE},
\wref{file:READ-LINE}{READ-LINE}.
\end{worddef}
\vspace*{-3ex}
\begin{worddef}{2485}{WRITE-LINE}
\item \stack{c-addr u fileid}{ior}
Write \param{u} characters from \param{c-addr} followed by the
implementation-dependent line terminator to the file identified
by \param{fileid} starting at its current position. \param{ior} is
the implementation-defined I/O result code.
At the conclusion of the operation, \word{FILE-POSITION} returns
the next file position after the last character written to the
file, and \word{FILE-SIZE} returns a value greater than or equal
to the value returned by \word{FILE-POSITION}.
\see \wref{file:READ-FILE}{READ-FILE},
\wref{file:READ-LINE}{READ-LINE}.
\begin{testing} % T.11.6.1.2485 WRITE-LINE
\ttfamily
\word{:} line1 \word{Sq} Line 1" \word{;}
\test{fn1 \word{W/O} \word{OPEN-FILE} \word{SWAP} fid1 \word{!}}{0} \\
\test{line1 fid1 \word{@} \word{WRITE-LINE}}{0} \\
\test{fid1 \word{@} \word{CLOSE-FILE}}{0}
\end{testing}
\end{worddef}
\subsection{File-Access extension words} % 11.6.2
\extended
\begin{worddef}{1524}{FILE-STATUS}
\item \stack{c-addr u}{x ior}
Return the status of the file identified by the character string
\param{c-addr u}. If the file exists, \param{ior} is zero;
otherwise \param{ior} is the implementation-defined I/O result
code. \param{x} contains implementation-defined information about
the file.
\end{worddef}
\vspace*{-3ex}
\begin{worddef}{1560}{FLUSH-FILE}
\item \stack{fileid}{ior}
Attempt to force any buffered information written to the file
referred to by \param{fileid} to be written to mass storage, and
the size information for the file to be recorded in the storage
directory if changed. If the operation is successful, \param{ior}
is zero. Otherwise, it is an implementation-defined I/O result
code.
\end{worddef}
\vspace*{-3ex}
\enlargethispage{6ex}
\begin{worddef}{1714}{INCLUDE}[]%[X:required]
\item \stack{i*x "name"}{j*x}
Skip leading white space and parse \param{name} delimited by a
white space character. Push the address and length of the
\param{name} on the stack and perform the function of
\word{INCLUDED}.
\see \wref{file:INCLUDED}{INCLUDED},
\rref{file:INCLUDE}{}.
\begin{rationale} % A.11.6.2.1714 INCLUDE
Typical use:
\begin{quote}
\word{INCLUDE} \texttt{filename}
\end{quote}
\end{rationale}
\begin{implement} % I.11.6.2.1714 INCLUDE
\word{:} \word{INCLUDE} \word{p} i*x "name" -{}- j*x ) \\
\tab \word{PARSE-NAME} \word{INCLUDED} \word{;}
\end{implement}
\begin{testing} % T.11.6.2.1714 INCLUDE
See \tref{file:REQUIRED}{REQUIRED}.
\pagebreak
\end{testing}
\end{worddef}
\begin{worddef}{2125}{REFILL}
\item \stack{}{flag}
Extend the execution semantics of \wref{core:REFILL}{REFILL}
with the following:
When the input source is a text file, attempt to read the next
line from the text-input file. If successful, make the result
the current input buffer, set \word[core]{toIN} to zero, and
return \emph{true}. Otherwise return \emph{false}.
\see \wref{core:REFILL}{REFILL},
\wref{block:REFILL}{REFILL}.
\end{worddef}
\begin{worddef}{2130}{RENAME-FILE}
\item \stack{c-addr_1 u_1 c-addr_2 u_2}{ior}
Rename the file named by the character string \param{c-addr_1 u_1}
to the name in the character string \param{c-addr_2 u_2}.
\param{ior} is the implementation-defined I/O result code.
\begin{testing} % T.11.6.2.2130 RENAME-FILE
\ttfamily
\word{:} fn3 \word{Sq} fatest3.txt" \word{;} \\
\word{:} >end fid1 \word{@} \word{FILE-SIZE} \word{DROP} fid1 \word{@} \word{REPOSITION-FILE} \word{;}
\test{fn3 \word{DELETE-FILE} \word{DROP}}{} \\
\test{fn1 fn3 \word{RENAME-FILE}}{0} \\
\word{bs} \textdf{\ Return value is undefined} \\
\test{fn1 \word{FILE-STATUS} \word{SWAP} \word{DROP} \word{0=}}{<FALSE>} \\
\test{fn3 \word{FILE-STATUS} \word{SWAP} \word{DROP} \word{0=}}{<TRUE> } \\
\test{fn3 \word{R/W} \word{OPEN-FILE} \word{SWAP} fid1 \word{!}}{0} \\
\test{>end}{0} \\
\test{\word{Sq} Final line" fid1 \word{@} \word{WRITE-LINE}}{0} \\
\test{fid1 \word{@} \word{FLUSH-FILE}}{0} \tab \word{bs} \textdf{Can only test \word{FLUSH-FILE} doesn't fail} \\
\test{fid1 \word{@} \word{CLOSE-FILE}}{0}
\word{bs} \textdf{Tidy the test folder} \\
\test{fn3 \word{DELETE-FILE} \word{DROP}}{}
\end{testing}
\end{worddef}
\begin{worddef}{2144}[10]{REQUIRE}[]%[X:required]
\item \stack{i*x "name"}{i*x}
Skip leading white space and parse \param{name} delimited by a
white space character. Push the address and length of the
\param{name} on the stack and perform the function of
\word{REQUIRED}.
\see \wref{file:REQUIRED}{REQUIRED},
\rref{file:REQUIRE}{}.
\begin{rationale} % A.11.6.2.2144.10 REQUIRE
Typical use:
\begin{quote}
\word{REQUIRE} \texttt{filename}
\end{quote}
\end{rationale}
\begin{implement} % I.11.6.2.2144.10 REQUIRE
\word{:} \word{REQUIRE} \word{p} i*x "name" -{}- i*x ) \\
\tab \word{PARSE-NAME} \word{REQUIRED} \word{;}
\end{implement}
\begin{testing} % T.11.6.2.2144.10 REQUIRE
See \tref{file:REQUIRED}{REQUIRED}.
\end{testing}
\end{worddef}
\enlargethispage{6ex}
\begin{worddef}{2144}[50]{REQUIRED}[]%[X:required]
\item \stack{i*x c-addr u}{i*x}
If the file specified by \param{c-addr u} has been \word{INCLUDED}
or \word{REQUIRED} already, but not between the definition and
execution of a marker (or equivalent usage of \word[tools]{FORGET}),
discard \param{c-addr u}; otherwise, perform the function of
\word{INCLUDED}.