ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Часть 8 МОДУЛЬ SYSTEM ============== Модуль SYSTEM играет особую роль в компиляторе JPI Modula-2, т.к. содержит зависящие от компилятора характеристики (а именно Ofs и Seg). Действительно, некоторые процедуры яв- ляются встроенными в компилятор, поэтому модуль также называется pseudo module (псевдо мо- дуль). SYSTEM также содержит типы данных, которые представляют интерес в этом конкретном при- менении. TYPE PROCESS = ADDRESS; Registers = RECORD CASE : BOOLEAN OF | TRUE : AX,BX,CX,DX,BP,SI,DI,DS,ES: CARDINAL; Flags : BITSET; | FALSE : AL,AH,BL,BH,CL,CH,DL,DH : SHORTCARD; END; END; CONST CarryFlag = 0; ZeroFlag = 6; VAR HeapBase : CARDINAL ; (* Базовый сегмент динамической области *) Тип Registers используется при выдаче запросов ДОСа и в прерываниях, т.к. доступ к внутренним регистрам процессора необходим при осуществлении этих действий. Тип PROCESS объясняется ниже. Низкоуровневые процессы ----------------------- Т.к. IBM PC/AT (и сравнимые с ним) являются компилятором с единственным процессором, действительно одновременные процессы не могут быть реализованы посредством сопрограмм. Сопрограмма - это последовательная программа, которая может быть приостановлена путем передачи выполнения другой сопрограмме (которая будет возобновлена с того места, в котором она была раньше приостановлена). Когда сопрограмма приостанавливается, ее текущее состояние сохраняется; таким образом, что она может возобновить свое выполнение позже, когда другая сопрограмма передаст выполнение обратно данной сопрограмме. В дальнейшем мы будем использовать термин процесс вместо сопрограммы. Система приоритетов модулей в JPI Мodula-2 ------------------------------------------ Система приоритетов модулей управляет обработкой аппаратных прерываний. Система прио- ритетов основана на контроллере аппаратных прерываний в компьютере РС/АТ. Приоритет интерп- ретируется как маска (BITSET-установка бита), который разрешает/запрещает отдельные преры- вания. Прерывание запрещено, если его соответствующий бит в маске установлен в 1. Чтобы использовать систему приоритетов, требуются некоторые знания о контроллере прерываний (см. "Технические ссылки"). На входе блока (тело PROCEDURE или тело MODULE), который имеет прио- ритет маски в контроллере прерываний и приоритет для блока, которые логически объединяются вместе; на выходе из блока маска в контроллере прерываний восстанавливается в то состояние, которое она имела на входе блока. АТ и РС отличаются тем, что АТ имеет 2 контроллера прерываний, а РС - только 1, т.к. АТ использует все 16 бит маски приоритета; 8 младших бит используются для установки маски в первичном контроллере прерываний, старшие 8 бит используются для установки главного конт- роллера. В случае РС только младшие 8 бит используются для установки маски в контроллере прерываний. Маска в контроллере прерываний считается частью состояния процесса; таким образом, она сохраняется и восстанавливается операциями TRANSFER и IOTRANSFER (см. процедуры ниже). Если IOTRANSFER связана с аппаратным прерыванием, обрабатываемым контроллером прерыва- ний, выдается неопределенный End-Of-Interrupt (конец прерывания). Запросы прерываний (IRQs), обрабатываемые аппаратурой, классифицированы через вектора прерываний от 08Н до 0FH для первичного контроллера и от 70Н до 77Н для главного контролле- ра. Это соответствует запросам прерываний от IRQ 0 - IRQ 15. Пример обработки прерывания: MODULE T; FROM SYSTEM IMPORT NEWPROCESS, IOTRANSFER, TRANSFER, CurrentPriority, NewPriority, ADRESS; VAR IntProc : ADDRESS; MODULE Int[CARDINAL{3}]; (* IRQ 3 выключено *) IMPORT IOTRANSFER; EXPORT IntHandler; PROCEDURE IntHandler; BEGIN ... IOTRANSFER( ..., 0BH); (* IOTRANSFER на IRQ 3 (Прерывание 0BH) *) END IntHandler; END Int; BEGIN ... NEWPROCESS( ...,IntProc ); TRANSFER( ...,IntProc ); NewPriority(CARDINAL(BITSET(CurrentPriority())-{3})); (* включено IRQ 3 *) END T. NEWPROCESS ---------- PROCEDURE NEWPROCESS ( P : PROC; A : ADDRESS; S : CARDINAL; VAR P1: ADDRESS); Создает новый процесс. Р - это лишенная параметров процедура, которая образует новый процесс. А - это указатель на рабочую область для процесса. Рабочая область необходима для локальных переменных и для хранения состояния процесса при его приостановке. S - это размер в байтах этой рабочей области. NEWPROCESS возвращает ссылку на заново созданный процесс в Р1. Заметим, что NEWPROCESS только приготавливает процесс для выполнения, он не вызывает начало его выполнения. TRANSFER -------- PROCEDURE TRANSFER(VAR P1,P2 : ADDRESS); Передает выполнение от одного процесса другому. Текущий процесс приостанавливается и назначается Р1, и процесс Р2 возобновляется (в его текущей точке приостановки). Р2 должен быть результатом предыдущего запроса к NEWPROCESS или TRANSFER. Процесс Р1 будет возобнов- лен позже, когда другой процесс передает выполнение обратно ему. Заметим, что назначение Р1 происходит после идентификации нового процесса Р2. Это зна- чит, что действительные параметры могут быть идентичными. Этот тип передачи называется синхронной передачей, что противоположно асинхронной пе- редаче, которая выполняется процедурой IOTRANSFER. IOTRANSFER ---------- PROCEDURE IOTRANSFER(VAR P1,P2: ADDRESS; I: CARDINAL); IOTRANSFER - это управляющая прерыванием (или асинхронная) передача. Она связывает те- кущий процесс с номером прерывания, данным в I. Затем она приостанавливает текущий процесс и назначает его Р1 и активизирует процесс, данный Р2. Когда процессор получает прерывание, он проверяет, связано ли это прерывание с процессом. Если это происходит, текущий процесс приостанавливается и назначается Р2, и (приостановленный) процесс Р1 возобновляется. Раз прерывание и результирующая IOTRANSFEER произошли вместе, то прерывание не будет больше связано с этим процессом. Если большее количество процессов связано с прерыванием I, они будут обработаны в сте- ке похожим образом, т.е. последний процесс, связанный с I будет активизирован, когда прои- зойдет первое прерывание I, второй от конца процесс будет активизирован, когда произойдет следующее прерывание I, и т. д. InterruptRegisters ------------------ PROCEDURE InterruptRegisters(P: ADDRESS) : ADDRESS; InterruptRegister может быть использован для доступа к содержимому регистров, когда происходит прерывание. Вызывать ее имеет смысл только тогда, когда имеет место IOTRANSFER к процессу Р. Она возвращает указатель на запись (на стек) со следующим расположением: TYPE ExtendedRegisters = RECORD r : Registers; (* как определено выше *) IP : CARDINAL; (* указатель команды *) CS : CARDINAL; (* кодовый сегмент *) RetFlags : CARDINAL; END; CurrentProcess -------------- PROCEDURE CurrentProcess() : ADDRESS; Возвращает ссылку на текущий процесс. CurrentPriority --------------- PROCEDURE CurrentPriority() : CARDINAL; Возвращает (MODULE) приоритет текущего процесса. NewPriority ----------- PROCEDURE NewPriority(PR : CARDINAL; Дает текущему процессу новый (MODULE) приоритет, определяемый PR, см. описание системы приоритетов выше. Listen ------ PROCEDURE Listen(Mask: BITSET); Listen временно разрешает прерывания, определенные с помощью Mask (маски), что разре- шает принимать ожидающие прерывания. Затем эта процедура восстанавливает маску прерываний в ее первоначальное состояние. ПРОЧИЕ ПРОЦЕДУРЫ ================ Компилятор генерирует внутренний код для всех процедур в этом разделе. DI -- PROCEDURE DI(); Запрещает аппаратные прерывания. Она полезна, когда имеется доступ к данным, которые являются общими для нескольких процессов. EI -- PROCEDURE EI(); Разрешает аппаратные прерывания. Ofs --- PROCEDURE Ofs(VAR A: WORD) : CARDINAL; Возвращает смещение адреса А. Заметим, что адреса состоят из смещения (Ofs) и адреса сегмента; физический адрес вычисляется как seg * 16 + ofs. Seg --- PROCEDURE Seg(VAR A: WORD) : CARDINAL; Возвращает адрес сегмента адреса А. Out --- PROCEDURE Out(P: CARDINAL; V: SHORTCARD); Выводит значение V в аппаратный порт Р. In -- PROCEDURE In(P: CARDINAL) : SHORTCARD; Возвращает значение из аппаратного порта Р. GetFlags -------- PROCEDURE GetFlags() : CARDINAL; Возвращает регистр флагов процессора. SetFlags -------- PROCEDURE SetFlags(F: CARDINAL); Устанавливает регистр флагов процессора в значение, определенное с помощью F. Процеду- ры SetFlags и GetFlags особенно полезны при запрещениях и разрешениях прерываний, для сох- ранения и восстановления предварительных значений флагов. МОДУЛЬ Process ============== Процедуры в этом модуле обрабатывают одновременные процессы. Т.к. JPI Мodula-2 реали- зуется на однопроцессорном компьютере, процессы делят между собой процессорное время пос- редством time-slicinq (разделение времени). Другие (более низкого уровня) процедуры процес- са могут быть найдены в модуле SYSTEM. ПЛАНИРОВЩИК ПРОЦЕССОВ ===================== StartScheduler -------------- PROCEDURE StartScheduler; Запускает процедуру разделения времени. Если она уже активна, этот запрос действия не имеет. StopScheduler ------------- PROCEDURE StopScheduler: Останавливает процедуру разделения времени. Заметим, что операции SEND и WAIT функцио- нируют до тех пор, пока процедура не остановится (см. "СИГНАЛЫ" ). StartProcess ------------ PROCEDURE StartProcess(P: PROC; N: CARDINAL; Pr: CARDINAL); Cоздает новый процесс, который выражается процедурой Р. Процесс будет распределять ра- бочую область размером N байт (N должен быть не более 1КБ). Каждый процесс имеет приоритет, который не должен быть перепутан с приоритетом MODULE. Pr - это приоритет процесса и должен быть больше нуля. Если Pr больше или равен приоритету текущего процесса, то заново создан- ный процесс станет активным. СИГНАЛЫ ======= Процессы могут взаимодействовать двумя различными путями: или благодаря глобальным разделяемым переменным, или благодаря сигналам. Сигналы используются для синхронизации про- цессов. Кроме инициализации, следующие операции могут быть выполнены на сигналах: SEND, WAIT, Notify, и Awaited. Сигнал состоит из двух категорий: счетчик и очередь. Init ---- TYPE SIGNAL; PROCEDURE Init (VAR s: SIGNAL ); Инициализирует сигнал s ( т.е. его счетчик установлен в 0, и очередь пуста). SEND ---- PROCEDURE SEND (s: SIGNAL ); Запрос SEND сделает активным 1-ый процесс, ждущий s. Если никаких процессов не ожида- ется, запрос будет поставлен в очередь. Операция SEND работает посредством возрастания счетчика, связанным с s. Если счетчик < = 0, то, по крайней мере, 1 процесс ждет s и 1-ый процесс в очереди будет готов к выпол- нению. Этот процесс также начнет выполняться, если его приоритет > = приоритета текущего процесса. Wait ---- PROCEDURE WAIT ( s: SIGNAL); Запрос WAIT заставляет запрашиваемый процесс ждать соответственно SEND, если сигнал s не имеет предварительно поставленных в очередь операций SEND. Процедура WAIT уменьшает счетчик, cвязанный с s. Если счетчик меньше 0, это значит, что запрашиваемый процесс должен ждать соответствующий SEND в s, и другой процесс будет ак- тивизирован. Если счетчик больше или равен 0, то запрашиваемый процесс будет продолжаться. Notify ------ PROCEDURE Notify (s: SIGNAL); Заставляет задачу, ждущую сигнал s, регистрироваться, когда возможно, т.е в следующий момент времени. Если никакой процесс не ждет s, то запрос не действует. Этот запрос не вы- зывает перерегистрацию, таким образом, он может использоваться устройством управления пре- рыванием (см.ГЛАВУ 7), чтобы безопасно обозначить другой процесс в момент, когда происходит событие. Awaited ------- PROCEDURE Awaited (s: SIGNAL): BOOLEAN; Возвращает TRUE (истина), если любой процесс ждет сигнал s (т.е., если счетчик, свя- занный с s, отрицателен). ПРОЧИЕ ПРОЦЕДУРЫ ================ Delay ----- PROCEDURE Delay (t : CARDINAL); Задерживает текущий процесс по меньшей мере на t интервалов времени. Интервал времени приблизительно 1/18 с. Если t=0, перерегистрация имеет место без задержки, разрешая другому процессу с таким же или большим приоритетом стать активным. Lock ---- PROCEDURE Lock; Lock предотвращает текущий процесс от перерегистрации с помощью интервала времени до тех пор, пока не будет запрошен Unlock. Это полезно, когда процесс использует данные, кото- рые разделяются между несколькими процессами. Запросы их к Lock могут быть вложены, но должны быть всегда спарены с запросами UnLock. Unlock ------ PROCEDURE Unlock; Unlock разрешает перерегистрацию в интервал времени, и должен быть всегда спарен с запросом Lock. Текущий процесс будет перерегистрирован, если в готовности находится процесс такого же или большего приоритета. Пример: Процесс работы с клавиатурой: MODULE KBP; IMPORT Process,IO; VAR (*$W+*) KBbuff : ARRAY[0..1023] OF CHAR; (* циклический буфер *) KBhead : CARDINAL; KBtail : CARDINAL; KeyReady: Process.SIGNAL; (*$W=*) PROCEDURE KBProcess; VAR k : CHAR; p : CARDINAL; BEGIN LOOP Process.Lock; (* Общие и ДОС-переменные использованы *) IF IO.KeyPressed() THEN k := IO.RdCharDirect(); p := (KBhead+1)MOD SIZE(KBbuff); IF p <> KBtail THEN KBbuff[KBhead] := k; KBhead := p; END; Process.Unlock; IF Process.Awaited(KeyReady) THEN Process.SEND(KeyReady) END; ELSE Process.Unlock; END; END; END KBProcess; PROCEDURE GetKey() : CHAR; VAR k : CHAR; BEGIN LOOP Process.Lock; (* Глобальные общие переменные использованы *) IF KBtail<>KBhead THEN k := KBbuff[KBtail]; KBtail := (KBtail+1)MOD SIZE(KBbuff); Process.Unlock; RETURN k; END; Process.Unlock; Process.WAIT(KeyReady); END; END GetKey; PROCEDURE InitKBProcess; BEGIN KBhead := 0; KBtail := 0; Process.Init(KeyReady); Process.StartProcess(KBProcess,1000,1); Process.StartScheduler; END InitKBProcess; VAR c : CHAR; BEGIN InitKBProcess; LOOP c :=GetKey(); Process.Lock; (* поскольку процедура IO.WrChar вызывает ДОС *) IO.WrChar(c); Process.Unlock; IF c=CHR(27) THEN EXIT END; END; END KBP. МОДУЛЬ MATHLIB ============== Процедуры из этого модуля выполняют общие математические вычисления. Кроме того, мо- дуль содержит некоторые процедуры, специфичные для микропроцессора Intel 8087. ОБРАБОТКА ОШИБОК ================ В случае ошибочных аргументов некоторые процедуры вызывают функции обработки ошибок, определенные ниже: MODULE MATHLIB VAR MathError : PROCEDURE (LONGREAL, ARRAY OF CHAR); MathError2 : PROCEDURE (LONGREAL, LONGREAL, ARRAY OF CHAR); Отмечаем, что процедуры обработки ошибок являются переменными типа "Процедура", кото- рые могут быть заменены процедурами, определенными пользователем. По умолчанию они присвое- ны процедурам MathError и MathError2 в модуле Lib. Процедуры обработки ошибок вызываются: MathError Sin, Cos, Tan, Asin, Acos, Log, Log10, Sqrt. MathError2 ATan2. Тригонометрические функции -------------------------- PROCEDURE Sin(A : LONGREAL) : LONGREAL; PROCEDURE Cos(A : LONGREAL) : LONGREAL; PROCEDURE Tan(A : LONGREAL) : LONGREAL; PROCEDURE ASin(A : LONGREAL) : LONGREAL; PROCEDURE ACos(A : LONGREAL) : LONGREAL; PROCEDURE ATan(A : LONGREAL) : LONGREAL; PROCEDURE ATan2(X,Y : LONGREAL) : LONGREAL; Sin, Cos и Tan осуществляют соответствующие математические функции. Аргумент А этих процедур определен в радианах. Sin и Cos возвращают значения в диапазоне от -1 до 1. ASin, ACos и ATan возвращают арксинус, арккосинус и арктангенс соответственно. Аргу- мент А у ASin и ACos должен быть в диапазоне от -1 до 1. ASin возвращает значения в диапа- зоне от -pi/2 до pi/2. ACos возвращает значения в диапазоне от 0 до pi. ATan возвращает значения в диапазоне от -pi/2 до pi/2. ATan2 возвращает арктангенс от X/Y. Результат - в диапазоне от -pi до pi. Гиперболические функции ----------------------- PROCEDURE SinH(A : LONGREAL) : LONGREAL; PROCEDURE CosH(A : LONGREAL) : LONGREAL; PROCEDURE TanH(A : LONGREAL) : LONGREAL; Эти процедуры возвращают гиперболический синус, гиперболический косинус и гиперболи- ческий тангенс соответственно переданного аргумента А. Натуральный логарифм -------------------- PROCEDURE Log(A: LONGREAL) : LONGREAL; Возвращает натуральный логарифм (по основанию е) аргумента А. Десятичный логарифм ------------------- PROCEDURE Log10(A : LONGREAL) : LONGREAL; Возвращает логарифм (по основанию 10) аргумента А. Степень числа ------------- PROCEDURE Pow(X,Y : LONGREAL) : LONGREAL; Возвращает X, возведенный в степень Y. Экспонента ---------- PROCEDURE Exp(A : LONGREAL) : LONGREAL; Возвращает результат возведения е в степень А (эта функция обратна Log). Модуль ------ PROCEDURE Mod(X,Y : LONGREAL) : LONGREAL; Возвращает X, являющийся абсолютной величиной Y. Rexp ---- PROCEDURE Rexp(VAR I: INTEGER; A: LONGREAL) : LONGREAL; Разбивает значение А на его экспоненту и мантиссу с помещением экспоненты в I, а ман- тисса - значение, возвращаемое функцией. Квадратный корень ----------------- PROCEDURE Sqrt(A: LONGREAL) : LONGREAL; Возвращает квадратный корень аргумента А. ПРОЦЕДУРЫ ПРЕОБРАЗОВАНИЯ ======================== Две процедуры, приведенные ниже, преобразуют целую часть вещественного значения в дво- ично-десятичное число и наоборот. Двоично-десятичное число представлено типом PackedBcd: TYPE PackedBcd = ARRAY [0..9] OF SHORTCARD; Две десятичные цифры упакованы в каждый элемент массива. Элемент номер 9 является зна- ком. LongToBcd --------- PROCEDURE LongToBcd(A: LONGREAL) : PackedBcd; Возвращает значение А в виде PackedBcd. А округляется к ближайшему целому. Например, a := LongToBcd(-12345.67); После этого вызова будем иметь значение: элемент: 9 8 7 6 5 4 3 2 1 0 шестнадцатеричное значение: 80 0 0 0 0 0 0 1 23 46 BcdToLong --------- PROCEDURE BcdToLong(A: PackedBcd) : LONGREAL; Возвращает LONGREAL представленные значения PackedBcd, заданного посредством А. ПРОЦЕДУРЫ СОПРОЦЕССОРА 8087 =========================== За описанием управляющего слова и среды микропроцессора 8087 обратитесь к вашей доку- ментации по 8087. LoadControlWord --------------- PROCEDURE LoadControlWord(C: BITSET); Загружает сопроцессор 8087 с управляющим словом, заданным посредством С. StoreControlWord ---------------- PROCEDURE StoreControlWord() : BITSET; Возвращает управляющее слово микропроцессора 8087. ClearExceptions --------------- PROCEDURE ClearExceptions(); Стирает флаги исключения, флаг запроса прерывания и флаг занятости в слове состояния микропроцессора 8087. StoreEnvironment ---------------- TYPE Environment = RECORD ControlWord : BITSET; StatusWord : BITSET; TagWord : BITSET; IP : CARDINAL; Opcode : CARDINAL; DataPointer : CARDINAL; R80287 : CARDINAL; END; PROCEDURE StoreEnvironment() : Environment; Возвращает среду процессора 8087, описанную посредством типа Environment. Смотри также документацию по сопроцессору 8087. МОДУЛЬ FIO ========== Процедуры этого модуля используются для обработки файлов и файлового ввода/вывода. FIO также содержит процедуры для обработки директорий. Файлу ставится в соответствие файловая позиция, которая изменяется при операциях запи- си и чтения. Первая позиция в файле - 0. Файлы являются последовательными, но прямой доступ к конкретным элементам в файле мо- жет быть достигнут посредством процедуры Seek. Перед тем, как файл может быть прочитан или записан, он должен быть открыт использова- нием одной из процедур Open, Create или Append. Эти процедуры все возвращают управляющую переменную файла, которая используется во всех последующих обращениях к этому файлу. Откры- тые файлы должны быть закрыты процедурой Close перед окончанием работы программы или когда они не будут более использоваться. ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ В FIO =========================== Эти переменные используются для управления поведением и проверки результатов процедур обработки файла и процедур ввода/вывода. CONST MaxOpenFiles = 15; DiskFull = 0F0H; (* Ошибка, если при записи файлов диск переполнен. *) StandardInput = 0; (* MS-DOS-стандартные номера файлов. *) StandardOutput = 1; ErrorOutput = 2; AuxDevice = 3; PrinterDevice = 4; TYPE File = CARDINAL; (* Тип файлового номера. *) VAR EOF : BOOLEAN; IOcheck : BOOLEAN; (* Если TRUE - ошибочное завершение программы с сообщением. *) Separators : Str.CHARSET; OK : BOOLEAN; ChopOff : BOOLEAN; Eng : BOOLEAN; (* Инженерное представление. *) Предопределенные MS-DOS-овские стандартные номера файлов именуются от 0 до 4 как это определено выше посредством констант. Пользовательские файлы нумеруются от 5 до значения MaxOpenFiles. Файлы, отмеченные стандартными номерами, определены, когда программа начинает выполнение, и не требуют открытия перед использованием. Булевская переменная ОК устанавливается всеми процедурами форматированного ввода/выво- да: WrBin и RdBin. Она указывает, была ли успешной предпринятая операция. Если сделана попытка записи форматированных данных в меньшую область, чем специфициро- вано, то записывается последовательность '?', если ChopOff - TRUE; в противном случае опи- санный размер поля превышается. ChopOff по умолчанию - FALSE. EOF устанавливается, если конец файла был достигнут во время последней операции чте- ния. Separators - множество разделителей данных, использующихся в процедуре RdItem. Значе- ние по умолчанию: CHARSET{CHR(9), CHR(13), CHR(26), ' '}. Eng устанавливается, если вещественные числа сформатированы в инженерном представлении (см. RealToStr). По умолчанию Eng - FALSE. Если IOcheck - TRUE, то ошибки, которые случатся во время выполнения процедур, пере- численных ниже, будут завершать программу с выдачей сообщения об ошибке. Если IOcheck - FALSE, ошибки вместо этого могут быть проверены посредством вызова процедуры IOresult. IOcheck по умолчанию TRUE. Следующие процедуры вызовут сообщения об ошибках, если IOcheck - TRUE: Open, Append, Create, Close, Truncate, GetPos, Seek, Size, Erase, Rename, ReadFirstEntry, ReadNextEntry, ChDir, MkDir, RmDir, GetDir. ОБРАБОТКА ФАЙЛОВ ================ Файлы являются по умолчанию небуферизованными, т.е. ДОС доступна для выполнения в лю- бое время операция чтения или записи. Для достижения большей эффективности ввода/вывода с файлом нужно связать буфер при помощи процедуры AssignBuffer с тем, чтобы пропускать к ДОС- у большие порции данных. Open ---- PROCEDURE Open(Name: ARRAY OF CHAR) : File; Открывает файл Name для чтения или записи и возвращает основу множества операций над файлом. Позиция файла устанавливается на начало файла. Если IOcheck - FALSE и специфициро- ванный файл не может быть открыт, возвращается значение MAX(CARDINAL). Append ------ PROCEDURE Append(Name: ARRAY OF CHAR) : File; Открывает файл Name, устанавливает позицию файла на конец файла, и возвращает номер открытого файла (или MAX(CARDINAL), если файл не был успешно открыт). Выполнение операций записи в непустой файл, открытый посредством Append, будет добавлять данные в файл вместо того, чтобы перезаписывать их. Create ------ PROCEDURE Create(Name: ARRAY OF CHAR) : File; Создает файл, специфицированный посредством Name, и возвращает номер этого файла (или MAX(CARDINAL), если файл не был успешно создан). Если файл уже существует, то предшествую- щее содержимое его теряется. Созданный файл открывается для операций чтения или записи. Close ----- PROCEDURE Close(F: File); Стирает буфер, соответствующий файлу F (если он существует) и затем закрывает файл. AssignBuffer ------------ PROCEDURE AssignBuffer(F : File; VAR Buf: ARRAY OF BYTE); Назначает буфер Buf файлу F. Для большой эффективности используемый размер буфера бу- дет: N*512+BufferOverHead, где N не меньше 2. Exists ------ PROCEDURE Exists(Name: ARRAY OF CHAR) : BOOLEAN; Возвращает TRUE, если специфицированный файл существует. Exists использует процедуру ReadFirstEntry для определения результата. Erase ----- PROCEDURE Erase(Name: ARRAY OF CHAR); Удаляет файл, заданный посредством Name. Rename ------ PROCEDURE Rename(Name,NewName : ARRAY OF CHAR); Переименовывает файл Name на NewName. Truncate -------- PROCEDURE Truncate(F: File); Отсекает файл F по его текущую файловую позицию. GetPos ------ PROCEDURE GetPos(F: File) : LONGCARD; Возвращает текущую файловую позицию файла F. Seek ---- PROCEDURE Seek(F : File; Pos: LONGCARD); Устанавливает файловую позицию файла F и помещает значение в Pos. Size ---- PROCEDURE Size(F: File) : LONGCARD; Возвращает размер файла F в байтах. IOresult -------- PROCEDURE IOresult() : CARDINAL; IOresult может быть вызвана после большинства операций для тестирования успешности операции. Нуль означает, что операция успешна, в противном случае IOresult возвращает код ошибки, определенный в ДОС. Заметьте, что глобальная переменная IOcheck должна быть FALSE для использования этой функции. ФОРМАТИРОВАННЫЙ ВЫВОД ===================== Процедуры, описанные ниже, выполняют форматированный вывод в файл. Процедура записи возможна для каждого простого типа JPI Modula-2. Все Wr'простой-тип' процедуры ( исключая WrChar) вызывают WrStrAdj. Wr'простой-тип' --------------- PROCEDURE WrChar(F : File; V : CHAR); PROCEDURE WrBool(F : File; V : BOOLEAN; Length:INTEGER); PROCEDURE WrShtInt(F:File; V:SHORTINT; Length:INTEGER); PROCEDURE WrInt(F : File; V : INTEGER; Length:INTEGER); PROCEDURE WrLngInt(F:File; V:LONGINT; Length:INTEGER); PROCEDURE WrShtCard(F:File; V:SHORTCARD; Length:INTEGER); PROCEDURE WrCard(F:File; V:CARDINAL; Length:INTEGER); PROCEDURE WrLngCard(F:File; V:LONGCARD; Length:INTEGER); PROCEDURE WrShtHex(F:File; V:SHORTCARD; Length:INTEGER); PROCEDURE WrHex(F:File; V:CARDINAL; Length:INTEGER); PROCEDURE WrLngHex(F:File; V:LONGCARD; Length:INTEGER); PROCEDURE WrReal(F:File; V:REAL; Precision:CARDINAL; Length:INTEGER); PROCEDURE WrLngReal(F:File; V:LONGREAL; Precision:CARDINAL; Length:INTEGER); Процедуры Wr'простой-тип' принимают следующие параметры: номер файла F, значение для записи V и размер поля форматированных данных Length (не применяется для WrChar). Если Length отрицательно, форматированные данные будут выровнены по левому краю, в противном случае - по правому краю. Все процедуры (исключая WrChar и WrBool) вызывают соответствующую процедуру преобразо- вания из модуля Str для получения строкового представления значения V (см. описание модуля Str); эта строка далее выводится с использованием WrStrAdj. Значение типа CARDINAL может быть записано в шестнадцатеричном формате посредством процедур WrShtHex, WrHex и WrLngHex. WrReal и WrLngReal принимают дополнительный параметр Precision, который имеет то же значение, что и в процедуре RealToStr (см. описание модуля Str). Глобальная переменная Eng указывает, сформатировано ли вещественное значение в инженерной нотации. WrStr ----- PROCEDURE WrStr(F:File; V: ARRAY OF CHAR); Записывает строку V в файл F. WrStrAdj -------- PROCEDURE WrStrAdj(F:File; S:ARRAY OF CHAR; Length: INTEGER); Записывает строку S в файл F, используя ABS(Length) как длину поля. Если ABS(Length) меньше, чем Str.Length(S) и глобальная переменная ChopOff - TRUE, то последовательность '?' записывается вместо S. Если Length отрицательна, то форматированные данные будут выров- нены по левому краю, в противном случае - по правому краю. Пример: WrStrAdj(StandardOutput,'Hello',10); WrLn(StandardOutput); WrStrAdj(StandardOutput,'Hello',-10); дает следующий вывод: Hello Hello WrCharRep --------- PROCEDURE WrCharRep(F:File; V:CHAR; Count:CARDINAL); Записывает символ V в файл F Count число раз. WrLn ---- PROCEDURE WrLn(F:File); Записывает новую строку (CHR(13) (возврат каретки), CHR (10) (перевод строки)) в файл F. WrBin ----- PROCEDURE WrBin(F:File; Buf:ARRAY OF BYTE; Count:CARDINAL); Записывает блок "необработанных" неформатированных данных, заданных посредством Buf в файл F. Count - размер блока в байтах. ФОРМАТИРОВАННЫЙ ВВОД ==================== Глобальная переменная EOF устанавливается в TRUE, если читается символ "конец-файла" (CHR(26)) или нет более входной информации, которую можно было бы прочитать из заданного файла. Rd'простой-тип' --------------- PROCEDURE RdChar (F : File) : CHAR; PROCEDURE RdBool (F : File) : BOOLEAN; PROCEDURE RdShtInt (F : File) : SHORTINT; PROCEDURE RdInt (F : File) : INTEGER; PROCEDURE RdLngInt (F : File) : LONGINT; PROCEDURE RdShtCard (F : File) : SHORTCARD; PROCEDURE RdCard (F : File) : CARDINAL; PROCEDURE RdLngCard (F : File) : LONGCARD; PROCEDURE RdShtHex (F : File) : SHORTCARD; PROCEDURE RdHex (F : File) : CARDINAL; PROCEDURE RdLngHex (F : File) : LONGCARD; PROCEDURE RdReal (F : File) : REAL; PROCEDURE RdLngReal (F : File) : LONGREAL; Все процедуры Rd'простой-тип' получают файловую управляющую F, специфицирующую файл, из которого будет производиться чтение, и возвращают значения 'простого типа', как указано в приведенном выше описании. Все процедуры (исключая RdChar) вызывают RdItem для получения последовательности сим- волов, которая ограничена символом из глобальной переменной типа множество Separators. Эта строка преобразуется к значению, используя одну из процедур преобразования из модуля Str. Процедуры RdShtHex, RdHex и RdLngHex читают значения типа CARDINAL в шестнадцатеричном формате. Процедура RdBool возвращает TRUE, если читает строку 'TRUE', для всех других выходных данных она возвращает FALSE. Синтаксис для имеющих силу значений типа REAL можно найти в ГЛАВЕ 6. Глобальная переменная ОК устанавливается в FALSE, если значение требуемого типа не мо- жет быть прочитано, т.е., если значение имеет недопустимый формат или значение. RdStr ----- PROCEDURE RdStr(F:File; VAR V:ARRAY OF CHAR); Читает строку из файла F и возвращает ее в V. Символы читаются до тех пор, пока не вы- полнится одно из следующих условий: - прочитан символ "конец файла" (CHR(26)), EOF установлен в TRUE, и V завершается ну- лем; - прочитан символ "возврат каретки" (CHR(13)). V завершается нулем; - строка заполнена, т.к. HIGH(V)+1 символов прочитано. V завершается не нулем. RdItem ------ PROCEDURE RdItem(F:File; VAR V: ARRAY OF CHAR); RdItem читает строку (из файла F), которая отделена посредством символов из глобальной переменной Separators. Строка возвращается в V. RdBin ----- PROCEDURE RdBin(F : File; VAR Buf : ARRAY OF BYTE; Count : CARDINAL) : CARDINAL; Читает блок размером Count "необработанных" байтов из файла F и возвращает его в Buf. ОБРАБОТКА КАТАЛОГОВ =================== ChDir ----- PROCEDURE ChDir(Name : ARRAY OF CHAR); Изменяет текущую директорию. Name специфицирует новый путь для директории и может включать имя устройства. MkDir ----- PROCEDURE MkDir(Name : ARRAY OF CHAR); Создает новую поддиректорию на пути, определенном посредством Name. RmDir ----- PROCEDURE RmDir(Name : ARRAY OF CHAR); Директория, специфицированная через Namе (которая должна быть пустой), исключается из структуры директорий. Заметим, что текущая директория не может быть исключена. GetDir ------ PROCEDURE GetDir( Drive : SHORTCARD; VAR Name : ARRAY OF CHAR); GetDir возвращает полное имя пути в Name для текущей директории на устройстве, специ- фицированная через Drive (0=по умолчанию, 1=устройство А и т.д.). ReadFirstEntry -------------- TYPE PathTail = ARRAY[0..12] OF CHAR; FileAttr = SET OF (readonly,hidden,system, volume,directory,archive); DirEntry = RECORD rsvd : ARRAY[0..20] OF SHORTCARD; (* зарезервировано *) attr : FileAttr; time : CARDINAL; date : CARDINAL; size : LONGCARD; name : PathTail; END; PROCEDURE ReadFirstEntry( DirName : ARRAY OF CHAR; Attr : FileAttr; VAR D : DirEntry) : BOOLEAN; Ищет директорию DirName, содержащую имя устройства, путь и имя файла для файла, кото- рый должен быть найден. Имя файла может содержать символы шаблона '*' и '?'. Параметр Attr требует некоторого объяснения: если он - пустое множество, то ищется только вхождение нор- мальных файлов (то же применяется, если установлены атрибуты readonly и archive); если должно быть взято в расчет вхождение скрытых файлов, системных файлов или директорий, то соответствующий атрибут должен быть установлен; наконец, если установлен атрибут volume, то возвращается только имя тома. Если подходящее вхождение найдено, ReadFirstEntry возвращает TRUE, и D будет содержать директорию вхождения. Смотри также процедуру ReadNextEntry. Пример: ReadFirstEntry("c:\com\*.*",FileAttr{hidden,system, directory},e) Подходящими будут все файлы директории "c:\com", и e будет содержать первое вхождение (если результат функции - TRUE). |