.TITLE GETCML - GET COMMAND LINE .IDENT /19MAY7/ ;09:00:00, LV ; .ENTRY GETCML - GET COMMAND LINE ;+ ; ; G E T C M L ; ; PURPOSE: THIS ROUTINE PROVIDES A SUBROUTINE INTERFACE TO ; THE DEC-SUPPLIED GET-COMMAND-LINE ROUTINE (.GCML). ; ; INTERFACE: CALLING SEQUENCE (FORTRAN CALLABLE SUBROUTINE) ; CALL GETCML (BUFFER [,PROMPT],LENGTH [,MAXLEN] ; 1 [,EOF] [,LUN] [,NOCLOS] [,COMMNTS]) ; ; INPUT: PROMPT = (BYTE ARRAY): 3 ASCII BYTES ; DEFINING DESIRED PROMPT STRING. ; AS THIS STRING IS WRITTEN TO THE ; TERMINAL, IT IS PREFIXED BY A LF AND ; CR, AND SUFFIXED BY A '>' SYMBOL. A ; ZERO BYTE SHOULD TERMINATE THE STRING. ; NEW FEATURE>> IF THE PROMPT STRING IS ; NOT EQUAL TO 3 BYTES, IT IS ASSUMED TO ; CONTAIN ITS OWN CARRIAGE CONTROL, AND ; MAY BE ANY LENGTH. NO PREFIXES OR ; SUFFIXES ARE ADDED. ; DEFAULT: 3 BLANKS ( ' >') ; ; MAXLEN = (INTEGER*2): MAXIMUM NUMBER OF CHARACTERS ; TO RETURN, IF USER INPUTS MORE THAN THIS ; NUMBER, AN ERROR MESSAGE WILL BE WRITTEN, ; AND ANOTHER TRY WILL BE MADE. ; IF MAXLEN<0, RETURN OF ZERO-LENGTH LINES ; IS ENABLED, AND MAXLEN=IABS(MAXLEN). ; DEFAULT: 80. ; ; LUN = (INTEGER*2): LUN TO USE FOR TERMINAL ; I/O, SHOULD BE ASSIGNED TO TI:. ; DEFAULT: 5 (TKB TI: DEFAULT) ; ; NOCLOS = (INTEGER*2): IF PRESENT AND NON-ZERO, ; CAUSES COMMAND FILE TO BE LEFT OPEN ; BETWEEN CALLS. THIS USES 512 BYTES ; OF FSR SPACE CONSTANTLY, AND PRECLUDES ; WRITING ERROR MESSAGES (THEY WOULD ; CLOBBER THE FILE). IT DOES INCREASE ; PROCESSING SPEED HOWEVER. (NOTE THAT ; ERROR MESSAGES FROM THIS ROUTINE WILL GO ; OUT OK, AS THE FILE IS ALWAYS CLOSED BEFORE ; WRITING A MESSAGE. USER WRITTEN MESSAGES ; WILL HAVE PROBLEMS, UNLESS AN ENTRY POINT ; TO CLOSE THE FILE IS ADDED. SEE I/O ; OPS MANUAL.) ; DEFAULT: CLOSE FILE BETWEEN CALLS. ; ; COMNTS = (INTEGER*2): IF PRESENT AND NON-ZERO, ; CAUSES LINES CONTAINING A LEADING SEMI- ; COLON TO BE RETURNED. ; DEFAULT: THROW OUT COMMENTS AND READ AGAIN ; ; OUTPUT: BUFFER = (BYTE ARRAY): THIS ARRAY IS FILLED ; WITH THE COMMAND LINE. IT MUST BE AT ; LEAST -MAXLEN- BYTES LONG. NOTE THAT THE ; LINE TERMINATOR IS NOT INCLUDED IN THIS ; BUFFER. ; ; LENGTH = (INTEGER*2): IS RETURNED AS NUMBER OF ; BYTES PLACED IN -BUFFER-. A ZERO LENGTH ; LINE IS NORMALLY NOT RETURNED (SEE ; -MAXLEN-). ; ; EOF = (LOGICAL*2): SET TO 177777 (FORTRAN ; .TRUE.) IF CNTRL-Z IS ENTERED, IF -EOF- ; IS NOT INCLUDED IN CALL, AN EXIT IS ; EXECUTED WHEN CNTRL-Z IS READ. ; ; EXAMPLES-- ; ; CALL GETCML (BUF,'PIP',LENGTH) ; CALL GETCML (BUF,,LEN,,,,1) ; ; LANGUAGE: MACRO-11 ; ; REFERENCES: THE I/O OPERATIONS MANUAL SHOULD BE CONSULTED FOR ; DETAILS OF OPERATION. ;- ; REVISIONS: ; 01:DEC-75 RSK WRITTEN ; 12-FEB-76 RSK FIXED PROBLEM WITH ODD-LENGTH PSECT. ; 02-MAR-76 RSK FIXED PROBLEM IN HANDLING -MAXLEN-.GT.127 ; 29-MAR-76 MK COMMENTED OUT F4P PSECTS AND TRACE CODE ; 02-SEP-76 SS MAKE RSX-11M COMPATIBLE ; 02-JAN-77 MK PUT GCML CONTROL BLOCK IN ITS OWN PSECT ($GCMLB) ; 03-MA6-77 LV UPDATED TO CONFORM TO STANDARDS ; ; PROGRAM DETAIL ; ; MACROS ; .MCALL GCMLD$,GCMLB$,EXIT$S,QIO$,DIR$,WTSE$S .MCALL CCML$ ; .MACRO TYPE,ERROR,?L CCML$ ;CLOSE COMMAND FILE MOV #ERROR'M,TYPE+Q.IOPL ;SET BUFFER ADDR MOV #ERROR'E-ERROR'M,TYPE+Q.IOPL+2 ;SET LENGTH DIR$ #TYPE BCS L WTSE$S #24. L: .ENDM TYPE ; ; .MACRO SEQNUM,NUMBER ; MOV #NUMBER,$SEQC ; .ENDM SEQNUM ; ; SYMBOL DEFINITIONS-- ; NESTS=3 ;DEPTH TO WHICH INDIRECTS CAN NEST GCMLD$ ;DEFINE GCML SYMBOLS LUN=5 ;DEFAULT LUN FOR I/O DEFARG=-1 ;ADDR OF DEFAULTED ARGUMENT TRUE=-1 ;FORTRAN .TRUE. FALSE=0 ;FORTRAN .FALSE. GE.BIG=177773 ;LINE-TOO-LONG ERROR NUMBER .GLOBL $OTSVA ; ; STORAGE ALLOCATION AND INITIALIZATION-- ; .PSECT $GCMLB,GBL,OVR CMLBLK: GCMLB$ NESTS,,,LUN .PSECT ; .PSECT $IDATA,RW,D,CON,LCL MAXLEN: .WORD 80. RET0: .BYTE 0 EOF: .BYTE 0 PROMPT: .BYTE LF,CR .ASCII / >/ .EVEN TYPE: QIO$ IO.WVB,LUN,24.,,,,<0,0,40,0,0,0> ; ; .PSECT $PDATA,RO,D,CON,LCL ;ME: .RAD50 /GETCML/ IORM: .ASCII *COMMAND I/O ERROR* IORE=. OPRM: .ASCII /OPEN FAILURE ON INDIRECT FILE/ OPRE=. BIFM: .ASCII /INDIRECT COMMAND SYNTAX ERROR/ BIFE=. MDEM: .ASCII /INDIRECT FILE DEPTH EXCEEDED/ MDEE=. BIGM: .ASCII /TOO MANY CHARACTERS IN LINE/ BIGE=. BADM: .ASCII /UNDECIPHERABLE GCML ERROR/ .EVEN BADE=. ; ; PROGRAM FLOW-- ; ; PROCESS AND/OR DEFAULT ARGUMENTS ; ; .PSECT $CODE1,RO,I,CON,LCL GETCML::;MOV ME+2,-(SP) ;2ND HALF OF ROUTINE NAME ; MOV ME,R4 ;1ST HALF OF ROUTINE NAME ; JSR R4,NAM$ ;CONNECT TO OTS TRACEBACK ; SEQNUM 1 MOV #CMLBLK,R0 ;ADDR OF CONTROL BLOCK CMP 4(R5),#DEFARG ;IS PROMPT STRING SPECIFIED? BEQ 1$ ;NO MOV 4(R5),G.PSDS+2(R0) ;SAVE ADDR OF USER STRING CLR G.PSDS(R0) ;ZERO THE LENGTH MOV 4(R5),R1 ;ADDR OF USER PROMPT 11$: TSTB (R1)+ ;LOOK FOR NULL CHARACTER BEQ 12$ INC G.PSDS(R0) ;BUMP CHARACTER COUNT BR 11$ 12$: CMP #3,G.PSDS(R0) ;IS STRING 3 BYTES LONG? BNE 2$ ;NO MOV #3,R1 ;COPY STRING INTO OUR PROMPT MOV 4(R5),R2 MOV #PROMPT+2,R3 13$: MOVB (R2)+,(R3)+ SOB R1,13$ MOV #6,G.PSDS(R0) ;HAVE GCML USE OUR PROMPT MOV #PROMPT,G.PSDS+2(R0) BR 2$ 1$: CLR G.PSDS(R0) ;FORCE USE OF DEFAULT STRING 2$: MOV #80.,MAXLEN ;DEFAULT MAXLEN CLRB RET0 ; AND RETURN-OF-ZERO-LENGTH-LINES CLRB EOF ; AND RETURN-OF-EOF MOVB #LUN,F.LUN(R0) ; AND GCML LUN MOVB #LUN,TYPE+Q.IOLU ; AND MESSAGE LUN BISB #GE.CLO!GE.COM,G.MODE(R0) ; AND CLOSE AND COMMENTS CMPB #4,@R5 ;4 ARGS? BGT GET ;NO CMP 10(R5),#DEFARG ;WAS MAXLEN SPECIFIED? BEQ 21$ ;NO MOV @10(R5),MAXLEN ;SET MAXLEN BPL 21$ ;DON'T RETURN ZLL INCB RET0 ;DO RETURN ZLL NEG MAXLEN ;MAKE MAXLEN POSITIVE 21$: CMPB #5,@R5 ;WERE AT LEAST 5 ARGS GIVEN? BGT GET ;NO CMP 12(R5),#DEFARG ;WAS EOF SPECIFIED? BEQ 22$ ;NO INCB EOF ;SET EOF FLAG MOV #FALSE,@12(R5) ;SET FLAG TO .FALSE. 22$: CMPB #6,@R5 ;DO WE HAVE AT LEAST 6 ARGS? BGT GET ;NO CMP 14(R5),#DEFARG ;WAS LUN SPECIFIED? BEQ 3$ ;NO MOVB @14(R5),F.LUN(R0) ;SET LUN IN FDB MOVB @14(R5),TYPE+Q.IOLU ; AND DPB 3$: CMPB #7,@R5 ;AT LEAST 7 ARGS? BGT GET ;NO CMP 16(R5),#DEFARG ;WAS NOCLOS SPECIFIED? BEQ 4$ ;NO TST @16(R5) ;WAS IT NON-ZERO? BEQ 4$ ;NO BICB #GE.CLO,G.MODE(R0) ;INDICATE "LEAVE OPEN" 4$: CMPB #10,@R5 ;8 ARGS? BGT GET ;NO CMP 20(R5),#DEFARG ;WAS COMNTS SPECIFIED? BEQ GET ;NO TST @20(R5) ;WAS IT NON-ZERO? BEQ GET ;NO BICB #GE.COM,G.MODE(R0) ;CLEAR THE PROPER BIT ; ; CONTROL BLOCK IS ALL SET UP. CALL SYSTEM ROUTINE TO GET INPUT. ; GET:; SEQNUM 2 CALL .GCML1 ;EXECUTE CALL BCS GCLERR ;IF EOF OR ERROR TST G.CMLD(R0) ;IS LINE ZERO LENGTH? BGT 5$ ;NO, RETURN IT TSTB RET0 ;ARE WE SUPPOSED TO RETURN ZLL? BEQ GET ;NO 5$: CMP G.CMLD(R0),MAXLEN ;IS LINE SHORT ENOUGH? BLE 51$ ;YES MOVB #GE.BIG,G.ERR(R0) ;SET ERROR CODE BR GCLERR ;PROCESS ERROR ; ; RETURN LINE AND LENGTH TO USER ; 51$:; SEQNUM 3 MOV G.CMLD(R0),@6(R5) ;RETURN LENGTH BEQ 7$ ;IF ZERO LENGTH MOV G.CMLD(R0),R1 ;PUT LENGTH IN REGISTER FOR COPY MOV G.CMLD+2(R0),R2 ;ADDR OF STRING MOV 2(R5),R3 ;ADDR OF USER BUFFER 6$: MOVB (R2)+,(R3)+ ;MOVE A CHARACTER SOB R1,6$ ;CONTINUE FOR ALL CHARACTERS 7$: RETURN ;THAT'S ALL ; ; C-BIT WAS SET BY .GCML: AN ERROR OR EOF OCURRED, ERROR CODE IS ; IN G.ERR OF CONTROL BLOCK. ; GCLERR:;SEQNUM 4 CMPB #GE.EOF,G.ERR(R0) ;IS IT AN EOF? BNE 10$ ;NO TSTB EOF ;DO WE RETURN AN EOF? BNE 7$ ;YES EXIT$S ;EXIT OTHERWISE 7$: MOV #TRUE,@12(R5) ;SET EOF TO FORTRAN LOGICAL .TRUE. RETURN ; ; ITS AN ERROR. DETERMINE WHICH ONE AND PUT OUT THE ; APPROPRIATE MESSAGE. ; 10$:; SEQNUM 5 CMPB #GE.IOR,G.ERR(R0) ;I/O ERROR? BNE L11 ;NO TYPE IOR BR GET L11: CMPB #GE.OPR,G.ERR(R0) ;OPEN FAILURE? BNE L12 ;NO TYPE OPR BR GET L12: CMPB #GE.BIF,G.ERR(R0) ;SYNTAX ERROR? BNE L13 ;NO TYPE BIF BR GET L13: CMPB #GE.MDE,G.ERR(R0) ;DEPTH EXCEEDED? BNE L14 ;NO TYPE MDE JMP GET L14: CMPB #GE.BIG,G.ERR(R0) ;LINE TOO LONG? BNE L15 ;NO TYPE BIG JMP GET L15: TYPE BAD ;WHO KNOWS? JMP GET .END