Cache': перехват текущего устройства

Cache': перехват текущего устройства

Евгений Каратаев

Эта заметка описывает программный перехват ввода-вывода текущего устройства в Cache'. Неудобство стандартных устройств mumps, а точнее определенного их поведения состоит в том, что если выполняется программный код, осуществляющий ввод-вывод через него, то этот процесс сторонним кодом неуправляем иначе как установкой возможных опций устройству. В то время как в некоторых случаях очень нужно иметь возможность выполнить так называемый унаследованный (legacy) код, который оперирует текущим устройством, но при этом в самих операциях ввода-вывода произвести дополнительные действия. 

Ситуация примерно аналогична вводу-выводу в сишном стиле и в стиле C++, когда в первом случае мы можем открыть файл и передать его коду, а во втором случае мы можем создать объект ввода-вывода и переопределить для него операции чтения - записи. 

Для перехвата операций ввода-вывода текущего устройства нужно 

Сделать отдельную рутину, в которой прописать функции, вызываемые при операциях ввода-вывода. 

Указать текущему устройству эту рутину как мнемоническую в команде use 

Включить перенаправление для текущего устройства 

В функциях переопределяющих операции ввода-вывода можно использовать штатное поведение текущего устройства если отключить перенаправление и при выходе из обработчика снова его включить. 

Рутина-перехватчик должна реализовать на свое усмотрение метки 

rstr(len,to)

Чтение с опциональным указанием заданной длины и таймаута

rchr(to)

Чтение номера символа

wstr(expr)

Запись строки W expr

wchr(expr)

Запись символа W *expr

wtab(expr)

Запись пропуска W ?expr

wnl

Перевод строки W !

wff

Очистка экрана W #

Шаблон рутины примерно такой: 

rstr(len,to) 

D $ZU(82,12,0) 

if $D(len)&&$D(to) d 

. ; перехват 

. R data#len:to 

e i $D(len) d 

. ; перехват 

. R data#len 

e i $D(to) d 

. ; перехват 

. R data:to 

e d 

. ; перехват 

. R data  

D $ZU(82,12,1) 

; перехват 

Q $G(data)

rchr(to) 

D $ZU(82,12,0) 

i $d(to) 

. ; перехват 

. R *data:to 

. ; перехват 

e d 

. ; перехват 

. R *data 

. ; перехват 

D $ZU(82,12,1) 

; перехват 

Q data 

// W expr

wstr(expr)  

D $ZU(82,12,0) 

; перехват 

W expr 

D $ZU(82,12,1) 

Q 

// W *expr 

wchr(expr)  

D $ZU(82,12,0) 

; перехват 

W *expr 

D $ZU(82,12,1) 

Q 

// W ?expr

wtab(expr) 

D $ZU(82,12,0) 

; перехват 

W ?expr 

D $ZU(82,12,1) 

Q 

// W !

wnl 

D $ZU(82,12,0) 

; перехват 

W !  

D $ZU(82,12,1) 

Q 

// W #

wff 

D $ZU(82,12,0) 

; перехват 

W #  

D $ZU(82,12,1) 

Q 

После чего можно пользоваться, указывая прехватчик:  

u dev::"^ИМЯРУТИНЫ" ; указываем какую мнемонику использовать 

D $ZU(82,12,1) ; реально включаем флаг использования 

d normal()  ; что будет писать в текущий девайс 

D $ZU(82,12,0) ; перед закрытием девайса возвращаем флажок 

c dev

Кроме программного назначения перехвата для обработки вывода наследованного кода можно использовать также и другие возможности: спулер, запись-чтение внешних файлов, межпроцессное взаимодействие.