.MACRO PUSH,ARGS .IRP .$1, MOV .$1,-(%6) .ENDR .ENDM .MACRO POP,ARGS .IRP .$1, MOV (%6)+,.$1 .ENDR .ENDM .TITLE GETCML -- GET COMMAND LINE .IDENT /030276/ ; ; SYSTEM/MACHINE - RSX-11D V6 / PDP-11 ; ; AUTHOR - RICHARD KITTELL, LASL MP-1 ; ; DATE - DECEMBER 1975 ; ; TYPE/LANGUAGE - FORTRAN CALLABLE SUBROUTINE / MACRO-11 ; ; RESIDENCE - [12,4]RTLIB.OLB, DECUSLIB ; ; MODIFICATIONS - 12-FEB-76: RSK ; FIXED PROBLEM WITH ODD-LENGTH PSECT. ; 02-MAR-76: RSK ; FIXED PROBLEM IN HANDLING -MAXLEN-.GT.127 ; ; ; ; ; ABSTRACT - THIS ROUTINE PROVIDES A SUBROUTINE INTERFACE ; THE THE DEC SUPPLIED GET-COMMAND-LINE ROUTINE (.GCML). THE I/O ; OPERATIONS MANUAL SHOULD BE CONSULTED FOR DETAILS OF OPERATION. ; ; ; ; 1. INTERFACE ; ; 1.1 CALLING SEQUENCE-- ; ; CALL GETCML (BUFFER [,PROMPT],LENGTH [,MAXLEN] [,EOF] [,LUN] ; 1 [,NOCLOS] [,COMNTS]) ; ; 1.2 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 WRITTING ; 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 WRITTING 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 ; ; 1.3 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. ; ; 1.4 EXAMPLES-- ; ; CALL GETCML (BUF,'PIP',LENGTH) ; CALL GETCML (BUF,,LEN,,,,1) ; ; 2. PROGRAM DETAIL ; ; 2.1 MACROS-- ; .MCALL GCMLD$,GCMLB$,EXIT$S,PUSH,POP,QIOW$,DIR$ .MCALL CCML$ ; .MACRO TYPE,ERROR 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 .ENDM TYPE ; .MACRO SEQNUM,NUMBER MOV #NUMBER,$SEQC .ENDM SEQNUM ; ; 2.2 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 ; ; 2.3 STORAGE ALLOCATION AND INITIALIZATION-- ; .PSECT $IDATA,RW,D,CON,LCL CMLBLK: GCMLB$ NESTS,,,LUN MAXLEN: .WORD 80. RET0: .BYTE 0 EOF: .BYTE 0 PROMPT: .BYTE LF,CR .ASCII / >/ .EVEN TYPE: QIOW$ IO.WVB,LUN,,,,,<0,0,40> ; .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=. ; ; 2.4 PROGRAM FLOW-- ; ; PROCESS AND/OR DEFAULT ARGUMENTS ; .PSECT $CODE1,RO,I,CON,LCL GETCML::PUSH ME+2 ;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 BR 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