( Файловый ввод-вывод. ) CREATE LT 0xD C, 0xA C, 0xD C, 0xA C, \ line terminator CREATE LTL 2 , \ line terminator length : DOS-LINES ( -- ) 0xA0D LT ! 2 LTL ! ; : UNIX-LINES ( -- ) 0xA0A LT ! 1 LTL ! ; : READ-FILE ( c-addr u1 fileid -- u2 ior ) \ 94 FILE \ Прочесть u1 символов в c-addr из текущей позиции файла, \ идентифицируемого fileid. \ Если u1 символов прочитано без исключений, ior ноль и u2 равен u1. \ Если конец файла достигнут до прочтения u1 символов, ior ноль \ и u2 - количество реально прочитанных символов. \ Если операция производится когда значение, возвращаемое \ FILE-POSITION равно значению, возвращаемому FILE-SIZE для файла \ идентифицируемого fileid, ior и u2 нули. \ Если возникла исключительная ситуация, то ior - определенный реализацией \ код результата ввода/вывода, и u2 - количество нормально переданных в \ c-addr символов. \ Неопределенная ситуация возникает, если операция выполняется, когда \ значение, возвращаемое FILE-POSITION больше чем значение, возвращаемое \ FILE-SIZE для файла, идентифицируемого fileid, или требуемая операция \ пытается прочесть незаписанную часть файла. \ После завершения операции FILE-POSITION возвратит следующую позицию \ в файле после последнего прочитанного символа. DUP >R .CODE 0! R@ .SIZE ! R@ .DATA ! R@ 70 SYS2 EBX@ SWAP DUP 6 = IF DROP 0 THEN DUP 0= IF R@ .FIRST D@ R@ .SIZE @ 0 D+ R@ .FIRST D! THEN RDROP ; 22 CONSTANT MAX_OPEN_FILES CREATE FILE_STR_BUF FILE_STR 1+ MAX_OPEN_FILES * ALLOT : FALLOC ( -- 0|fid ) FILE_STR_BUF FILE_STR MAX_OPEN_FILES * BOUNDS BEGIN DUP .NAME @ 0= IF NIP EXIT THEN FILE_STR + 2DUP U< UNTIL 2DROP 0 ; : OPEN-FILE ( c-addr u fam -- fileid ior ) \ Открыть файл с именем, заданным строкой c-addr u, с методом доступа fam. \ Смысл значения fam определен реализацией. \ Если файл успешно открыт, ior ноль, fileid его идентификатор, и файл \ позиционирован на начало. \ Иначе ior - определенный реализацией код результата ввода/вывода, \ и fileid неопределен. DROP \ FILE_STR FALLOC DUP IF >R R@ FILE_STR ERASE R@ .NAME SWAP MOVE R> 0 EXIT THEN -1 ; : CLOSE-FILE ( fileid -- ior ) \ 94 FILE \ Закрыть файл, заданный fileid. .NAME 0! 0 ; USER _fp1 USER _fp2 USER _addr : READ-LINE ( c-addr u1 fileid -- u2 flag ior ) \ 94 FILE \ Прочесть следующую строку из файла, заданного fileid, в память \ по адресу c-addr. Читается не больше u1 символов. До двух \ определенных реализацией символов "конец строки" могут быть \ прочитаны в память за концом строки, но не включены в счетчик u2. \ Буфер строки c-addr должен иметь размер как минимум u1+2 символа. \ Если операция успешна, flag "истина" и ior ноль. Если конец строки \ получен до того как прочитаны u1 символов, то u2 - число реально \ прочитанных символов (0<=u2<=u1), не считая символов "конец строки". \ Когда u1=u2 конец строки уже получен. \ Если операция производится, когда значение, возвращаемое \ FILE-POSITION равно значению, возвращаемому FILE-SIZE для файла, \ идентифицируемого fileid, flag "ложь", ior ноль, и u2 ноль. \ Если ior не ноль, то произошла исключительная ситуация и ior - \ определенный реализацией код результата ввода-вывода. \ Неопределенная ситуация возникает, если операция выполняется, когда \ значение, возвращаемое FILE-POSITION больше чем значение, возвращаемое \ FILE-SIZE для файла, идентифицируемого fileid, или требуемая операция \ пытается прочесть незаписанную часть файла. \ После завершения операции FILE-POSITION возвратит следующую позицию \ в файле после последнего прочитанного символа. DUP >R FILE-POSITION IF 2DROP 0 0 THEN _fp1 ! _fp2 ! 1+ OVER _addr ! R@ READ-FILE ?DUP IF NIP RDROP 0 0 ROT EXIT THEN DUP >R 0= IF RDROP RDROP 0 0 0 EXIT THEN \ были в конце файла _addr @ R@ LT 1+ 1 SEARCH IF \ найден разделитель строк DROP _addr @ - DUP 1+ S>D _fp2 @ _fp1 @ D+ RDROP R> REPOSITION-FILE DROP DUP _addr @ + 1- C@ 0xD = IF 1- THEN ELSE \ не найден разделитель строк 2DROP R> RDROP \ если строка прочитана не полностью - будет разрезана THEN TRUE 0 ; : FILE-POSITION ( fileid -- ud ior ) \ 94 FILE \ ud - текущая позиция в файле, идентифицируемом fileid. .FIRST D@ 0 ; : REPOSITION-FILE ( ud fileid -- ior ) \ 94 FILE \ Перепозиционировать файл, идентифицируемый fileid, на ud. .FIRST D! 0 ;