!%externalroutinespec Console %alias "3L_IMP_CONSOLE"(%string(255) S) ! ! >>> STREAMS <<< ! ! Basic stream-handling package for the new I/O system. ! ! This module provides the basic stream manipulation primitives, ! without knowing quite what a stream might be made of. ! %from IMP %include Formats, Buffers, HandCall, MCode, Depio %record %format PDL Fm (%record(PDL Fm) %name PDL, %record(SCB Fm) %name SCB, %integer Level) %const %record(PDL Fm) %name PDL == 0 %const %integer Max Streams = 15 %record %format Stream Vector(%record(PDL Fm)%name %array Stream(0: Max Streams) ) %external %integer %spec Level %alias "3L___io_level" %external %integer - In Str %alias "3L___in_stream" = 0, {number of currently selected input} Out Str %alias "3L___out_stream" = 0 {number of currently selected output} %external %record(Stream Vector) In %alias "3L___in_vector" = 0 %external %record(Stream Vector) Out %alias "3L___out_vector" = 0 {###################################################################} {###################################################################} {### ###} {### E R R O R C H E C K I N G A N D R E P O R T I N G ###} {### ###} {###################################################################} {###################################################################} ! ! >> EOF << ! ! This routine signals EOF (9,1,0) in a consistent way throughout the RTS ! %external %routine Eof %alias "3L___eof" %signal 9, 1, 0 %end ! ! >> CHECK STREAM << ! %external %routine Check Stream %alias "3L___check_stream" (%integer S) %signal 9, 2, S %unless 0 <= S <= Max Streams %end {###########################################} {###########################################} {### ###} {### S T R E A M S E L E C T I O N ###} {### ###} {###########################################} {###########################################} ! ! >> SELECT INPUT << ! %external %routine Select Input %alias "3L_IMP_SELECT_INPUT" (%integer Stream) %signal 9, 2, Stream %unless 0 <= Stream <= Max Streams In Str = Stream In SCB == In_Stream(Stream)_SCB %end ! ! >> SELECT OUTPUT << ! %external %routine Select Output %alias "3L_IMP_SELECT_OUTPUT" (%integer Stream) %signal 9, 2, Stream %unless 0 <= Stream <= Max Streams Out Str = Stream Out SCB == Out_Stream(Stream)_SCB %end {#########################################} {#########################################} {### ###} {### S T R E A M P U S H / P O P ###} {### ###} {#########################################} {#########################################} ! ! >> PUSH INPUT STREAM << ! %external %routine Push Input %alias "3L___push_input_stream" - (%integer Stream, %record(SCB Fm) %name S) %record(PDL Fm) %name P Check Stream(Stream) P == New(PDL) P_SCB == S; P_PDL == In_Stream(Stream); P_Level = Level In_Stream(Stream) == P Select Input(In Str) %end ! ! >> PUSH OUTPUT STREAM << ! %external %routine Push Output %alias "3L___push_output_stream" ( %integer Stream, %record(SCB Fm) %name S ) %record(PDL Fm) %name P Check Stream(Stream) P == New(PDL) P_SCB == S; P_PDL == Out_Stream(Stream); P_Level = Level Out_Stream(Stream) == P Select Output(Out Str) %end {#######################################################################} {#######################################################################} {### ###} {### I N I T I A L I S A T I O N & N U L L F A C I L I T Y ###} {### ###} {#######################################################################} {#######################################################################} %own %record(SCB Fm) Null In = 0, Null Out = 0 %constinteger Null Buffer Size = 15 %own %string(13) Null Name = "" %own %byte %array Null Chs (0: Null Buffer Size-1) ! ! >> NULL FULL << ! %external %routine Null Full %alias "3L___null_full" {R1 = addr(SCB)} {R1 = Char} %record(SCB Fm) %name S *STR _ R1, S S_Next = S_ThisB_Base %end ! ! >> OPEN NULL INPUT << ! %external %routine Open Null Input %alias "3L_IMP_OPEN_NULL_INPUT" - (%integer Stream) Push Input(Stream,Null In) %end ! ! >> OPEN NULL OUTPUT << ! %external %routine Open Null Output %alias "3L_IMP_OPEN_NULL_OUTPUT" - (%integer Stream) Push Output(Stream,Null Out) %end ! ! >> STREAM INIT << ! ! Initialise the stream I/O package. This opens a NULL stream on ! every stream, both for input and output. These are opened at level 0. ! Level is then raised to 1. NB level 0 streams are NEVER EVER popped. ! ! Subsequent calls on STREAM INIT just up the level number again. ! The initialisation package calls us twice, once after the definitions ! for stream 0 and 1 have been overlaid. This leaves LEVEL at 2 for ! execution of user programs. ! %external %routine Stream Init %alias "3L___stream_init" %integer I, D1, D2 %if Level = 0 %start D1 = Addr 1(Dummy 1) D2 = Addr 2(Dummy 2) Null In _Buffer Handler = Addr 0 (EOF) Null In_Reset Handler = D1; Null Out_Reset Handler = D1 Null In_Close Handler = D2; Null Out_Close Handler = D2 Null In_Position Handler = D2; Null Out_Position Handler = D2 Null In_NameB_Base = Addr(Null Name) Null Out_NameB_Base = Addr(Null Name) Null Out_Next = Addr(Null Chs(0)) Null Out_ThisB_Base = Addr(Null Chs(0)) Null Out_ThisB_Size = Null Buffer Size Null Out_Limit = Null Out_Next + Null Buffer Size Null Out_Breaks = -1 Null Out_Complete Handler = D1 Null Out_Reset Handler = D1 Null Out_Buffer Handler = Addr 0 (Null Full) %for I = 0, 1, Max Streams %cycle Open Null Input (I) Open Null Output(I) %repeat %finish Select Input(1) Select Output(1) Level = Level+1 {protect level 0 streams} %end {#################################################} {#################################################} {### ###} {### C O M M O N C L O S I N G C O D E ###} {### ###} {#################################################} {#################################################} %routine ABC(%record(Stream Vector) %name SV, %integer AC, Str) %record(SCB Fm) %name S %record(PDL Fm) %name P == SV_Stream(Str) %return %if P_Level = 0 %or P_Level < Level {not ours or bottom level} SV_Stream(Str) == P_PDL Dispose(P) S == P_SCB S_Flags = S_Flags ! AC Close SCB(S, AC) %end {###################################################} {###################################################} {### ###} {### W I N D D O W N P R O C E D U R E S ###} {### ###} {###################################################} {###################################################} %external %routine Wind Down %alias "3L___stream_wind" %integer Sno Level = Level - 1 %for Sno = 0, 1, Max Streams %cycle ABC( In, 0, Sno) %while In_Stream(Sno)_Level > Level ABC(Out, 0, Sno) %while Out_Stream(Sno)_Level > Level %repeat Select Input(1); Select Output(1) %end {#####################################################} {#####################################################} {### ###} {### U S E R L E V E L P R O C E D U R E S ###} {### ###} {#####################################################} {#####################################################} ! ! >> CLOSE INPUT << ! %external %routine Close Input %alias "3L_IMP_CLOSE_INPUT" ABC(In, 0, In Str) Select Input(In Str) %end ! ! >> CLOSE OUTPUT << ! %external %routine Close Output %alias "3L_IMP_CLOSE_OUTPUT" ABC(Out, 0, Out Str) Select Output(Out Str) %end ! ! >> ABANDON INPUT << ! %external %routine Abandon Input %alias "3L_IMP_ABANDON_INPUT" ABC(In, SCB Flag Abandoned, In Str) Select Input(In Str) %end ! ! >> ABANDON OUTPUT << ! %external %routine Abandon Output %alias "3L_IMP_ABANDON_OUTPUT" ABC(Out, SCB Flag Abandoned, Out Str) Select Output(Out Str) %end