; 00021 .INCLUDE "LB:[MACROS]MACROS.MAC" MODULE CommonUCS, MNAME=CUCS, VER=03, LIBR=YES, COMM= .REM % ------------------------------------------------------------ | Copyrigth (c) 1994 by WAS, Saratov, Russia. | | All rights reserved. | ------------------------------------------------------------ Автор: X.X. Xxxxxxx, г. Саратов, 9 января 1994 г. Функция: перекодировка ASCII в другие кодировки в текстовых файлах. Замечание: в случае ошибок в операциях OPEN, GET, PUT или CLOSE для вывода сообщений об ошибках используется программа "МО". Сама программа, а также ее исходный текст могут быть получены у автора (г. Саратов). Изменения: 6 мая 1988 г. - исходная версия V01.01 28 июня 1988 г. - добавлен код для V01.02 multi-buffering FCS-11 20 декабря 1988 г. - добавлено использование VX0103 big-buffering FCS-11 9 января 1994 г. - common версия: WAS.02 15 января 1994 г. - добавлена возможность WAS.03 коммандной строки в виде file1=file2 % ; Variants ; ; MBF = 1 - один буфер для файла ; MBF >= 2 - n буферов для файла ; (только для FCS-11 с поддержкой multi-buffering) ; MBF=2. ; ; OBS = 1 - 512.-ти байтный буфер ; OBS >= 2 - n*512.-ти байтный буфер ; (только для FCS-11 с поддержкой big-buffering) ; OBS=20. ; ; E$GCML = 0 - использовать стандартный GCML ; E$GCML = 1 - использовать расширенный GCML ; E$GCML=0 ;;;; .IIF NDF MBF MBF=1 .IIF LE MBF-1 MBF=1 .IIF NDF OBS OBS=1 .IIF LE OBS-1 OBS=1 .IIF NDF E$GCML E$GCML=0 ;;;; FROM SYSMAC IMPORT DIR$, ALUN$, QIOW$ FROM SYSMAC IMPORT GREG$S, EXTK$S, SDRC$S, STSE$S, WSIG$S FROM SYSMAC IMPORT FCSMC$, FCSBT$, FDOF$L, FSROF$ .IIF EQ E$GCML FROM SYSMAC IMPORT GCMLD$, GCMLB$, GCML$ .IIF NE E$GCML FROM SYSMAC IMPORT EGCMI$ FROM SYSMAC IMPORT CSI$, CSI$1, CSI$2 FROM SYSLIB.QIOSYM IMPORT IE.UPN, IE.EOF, TF.CCO FROM SYSLIB.VCTDF IMPORT $DSW, .FSRPT FROM SYSLIB.FCSTYP IMPORT .FCTYP FROM SYSLIB.RQLCB IMPORT $RLCB FROM MAIN IMPORT $CTAB ;;;; EXPORT QUALIFIED CUCS ;;;; MAXD = 1 ; макс. вложенность ККФ CLUN = 1 ; lun ввода комманд ILUN = 2 ; lun входного файла OLUN = 3 ; lun выходного файла MXRLEN = 256. ; макс. длина строки в файле FCSMC$ FCSBT$ FDOF$L FSROF$ DEF$L .IIF NE E$GCML EGCMI$ GCMLD$ CSI$ ; ; Constants ; NBF1=3 ; simple version NBF2=*2+1 ; big only NBF3=*2+1 ; multi only NBF4=*2+1 ; big & multi-buffering FCS-11 SPSZ1=NBF1*<512.+S.BFHD> SPSZ2=NBF2*<512.+S.BFHD> SPSZ3=NBF3*<512.+S.BFHD> SPSZ4=NBF4*<512.+S.BFHD> FSRSZ$ 0 $PRINT $IDATA GREG: INP: BUF: .LIMIT .=INP .BLKB MXRLEN .EVEN PROCEDURE INIT $PDATA CALUN: ALUN$ CLUN, TI, 0 IALUN: ALUN$ ILUN, SY, 0 OALUN: ALUN$ OLUN, SY, 0 .IIF NE FT.BBF-2 .ERROR .IIF NE FT.MBF-4 .ERROR FCSTYP: .WORD SPSZ1 ; simple .WORD SPSZ2 ; FT.BBF .WORD SPSZ3 ; FT.MBF .WORD SPSZ4 ; FT.BBF & FT.MBF $IDATA QINIT: .WORD 0 BEGIN IF QINIT EQ #0 THEN DIR$ #CALUN DIR$ #IALUN DIR$ #OALUN MOV @#.FSRPT, R1 IF RESULT IS EQ THEN BPT END IF A.DFUI(R1) EQ #0 THEN FINIT$ ; инициализация FCS-11 END CALL .FCTYP ; получить тип FCS-11 BIC #^C, R1 .IIF NE FT.BBF-2 .ERROR .IIF NE FT.MBF-4 .ERROR MOV FCSTYP(R1), R1 ; сколько надо памяти MOV INP+2, R2 ; конец задачи по построению MOV #GREG, R3 ; получить размер задачи в памяти GREG$S , R3 ; от Executive'а MOV G.RGRS(R3), R3 ASH #6, R3 ; в байты SUB R2, R3 ; сейчас свободно SUB R3, R1 ; требуемое-имеемое ADD #77, R1 ; выравнивание ASH #-6, R1 ; в кол-во 100(8) байтных блоков EXTK$S R1 ; расширить MOV #GREG, R1 ; получить новый размер задачи GREG$S , R1 ; от Executive'а MOV G.RGRS(R1), R1 ; в R1 ASH #6, R1 ; в байты SUB R2, R1 ; размер свободной памяти MOV @#.FSRPT, R0 ; free memory listhead CALL $RLCB ; отдать INC QINIT ; инициализация проведена END RETURN END INIT PROCEDURE CALLMO $PDATA MO: .RAD50 /MO..../ BEGIN SUB #11.*2, SP ; 11 пустых слов MOV #3*400+1, R1 ; 3 - серьезность ошибки, 1 - ошибка директивы IF R0 PL #0 THEN ; если R0 положительно, то NEGB R0 ; сделать положительным байт INC R1 ; а ошибка - ошибка в/в ELSE ; иначе NEG R0 ; сделать положительным слово END ; все PUSH R0 ; второе слово - код ошибки PUSH R1 ; первое слово - тип ошибки MOV SP, R1 ; указатель на буфер посылки LOOP ; цикл SDRC$S #MO, R1, #1 ; послать сообщение MO.... IF RESULT IS CC LEAVE LOOP ; если все в порядке - покинуть цикл MOV @#$DSW, R0 ; код ошибки - в R0 IF R0 NE #IE.UPN THEN ; если код не "нехватка динамической памяти", то BPT ; запрос отладчика (или завершить задачу) END ; все WSIG$S ; подождать важное событие END ; и повторить STSE$S #1 ; ждем вывода сообщения ADD #13.*2, SP ; очистить стек SEC ; была ошибка и вызов CALLMO RETURN ; возврат END CALLMO PROCEDURE FIERR BEGIN MOV IFDB+F.ERR, R0 BR CALLMO END FIERR PROCEDURE OIERR BEGIN PRINT BR FIERR END OIERR PROCEDURE GIERR BEGIN PRINT BR FIERR END GIERR PROCEDURE FOERR BEGIN MOV OFDB+F.ERR, R0 BR CALLMO END FOERR PROCEDURE OOERR BEGIN PRINT BR FOERR END OOERR PROCEDURE POERR BEGIN PRINT BR FOERR END POERR $IDATA CSIBLK: .BLKB C.SIZE .EVEN IFDB: FDBDF$ FDRC$A FD.PLC!FD.INS, BUF, MXRLEN FDOP$A ILUN, CSIBLK+C.DSDS, DFNB FDBF$A , OBS*512., MBF DFNB: NMBLK$ TXT, TXT, 0, SY, 0 OFDB: FDBDF$ FDRC$A FD.INS FDOP$A OLUN, CSIBLK+C.DSDS, DFNB FDBF$A , OBS*512., MBF PROCEDURE CSI1 BEGIN CSI$2 #CSIBLK, OUTPUT ; взять выходной IF RESULT IS CC THEN FDBF$R #IFDB, , , ,#FD.RAH ; Multi-buffering для чтения OPNS$R ; открыть входноя файл IF RESULT IS CC THEN ; если все ок, то MOV #IFDB+F.FNB, R0 ; скопировать FDB FNB входного файла MOV #OFDB+F.FNB, R1 ; в FDB FNB выходного файла THRU R2 := #S.FNBW ; длина FNB в словах MOV (R0)+, (R1)+ ; пересылка END FDBF$R #OFDB, , , ,#FD.WBH ; Multi-buffering для записи OPNS$M ; открытие по FID'у IF RESULT IS CS THEN ; если есть ошибка, то CLOSE$ #IFDB ; закрыть входной FDB CALLR OOERR ; вызвать MO.... END ; с ошибкой открытия выходного файла ELSE CALLR OIERR ; вызвать MO.... END ; с ошибкой открытия входного файла ELSE PRINT SEC END RETURN END CSI1 PROCEDURE CSI2 BEGIN CSI$2 #CSIBLK, INPUT ; взять входной IF RESULT IS CC THEN FDBF$R #IFDB, , , ,#FD.RAH ; Multi-buffering для чтения OPNS$R ; открыть входноя файл IF RESULT IS CC THEN ; если все ок, то CSI$2 #CSIBLK, OUTPUT ; взять выходной IF RESULT IS CC THEN FDBF$R #OFDB, , , ,#FD.WBH ; Multi-buffering для записи FDAT$R , IFDB+F.RTYP, IFDB+F.RATT, IFDB+F.RSIZ OPNS$W ; открыть выходноя файл IF RESULT IS CS THEN ; если есть ошибка, то CLOSE$ #IFDB ; закрыть входной FDB CALLR OOERR ; вызвать MO.... END ; с ошибкой открытия выходного файла ELSE PRINT SEC END ELSE CALLR OIERR ; вызвать MO.... END ; с ошибкой открытия входного файла ELSE PRINT SEC END RETURN END CSI2 PROCEDURE CSI $ASCII PRMPT: .ASCII <15><12>/CommonUCS>/ PRMP.L=.-PRMPT $IDATA GCML: .IIF EQ E$GCML GCMLB$ MAXD, UCS, INP, CLUN, , MXRLEN .IIF NE E$GCML GCML: ECMLB$ , CLUN, MAXD, UCS, INP, MXRLEN BEGIN CSI$1 #CSIBLK, GCML+G.CMLD+2, GCML+G.CMLD ; проверить синтаксис IF RESULT IS CC THEN IFB #CS.EQU OFF.IN CSIBLK+C.STAT THEN CALL CSI1 ELSE CALL CSI2 END ELSE PRINT SEC END RETURN END CSI PROCEDURE CUCS BEGIN CALL INIT ; MOVB #GE.COM!GE.IND!GE.SIZ, GCML+G.MODE ; умолчание LOOP GCML$ #GCML, #PRMPT, #PRMP.L ; получить коммандную строку IF RESULT IS CS THEN ; если ошибка IFB GCML+G.ERR NE #IE.EOF THEN ; и ошибка - не ^Z PRINT END RETURN END IF GCML+G.CMLD NE #0 THEN ; не пустая строка CALL CSI IF RESULT IS CC THEN REPEAT GET$ #IFDB ; очередная запись IF RESULT IS CS THEN ; если ошибка IFB IFDB+F.ERR NE #IE.EOF THEN ; и не eof CALL GIERR ; вызвать MO.... END SEC ELSE MOV IFDB+F.NRBD+2, R0 ; адрес записи MOV IFDB+F.NRBD, R1 ; ее длина MOV R0, R2 ; сохранить MOV R1, R3 ; в R2 и R3 IF RESULT IS NE THEN ; пустая строка - ничего не делать THRU R1 ; конвертирование CLR R5 BISB (R0), R5 MOVB $CTAB(R5), (R0)+ END END PUT$ #OFDB, R2, R3 ; вывести в файл IF RESULT IS CS THEN ; если ошибка CALL POERR END END UNTIL RESULT IS CS CLOSE$ #IFDB CLOSE$ #OFDB END END END END CUCS END CommonUCS .END