.TITLE GREP -- GET REPRESENTATION .IDENT /2.04/ .ENABL LC ; 2.01 ;+ ; ABSTRACT: GREP ; ; THIS PROGRAM WILL PRINT OUT ALL FILES WHICH HAVE A SPECIFIC ; STRING CONTAINED IN THEM, AND PRINT THE LINES IN THE FILES ; WHICH CONTAIN THE STRING. ; ; OPERATING PROCEDURES: ; ; >GREP [[/SP][/AP] =] /SE:[/WI:n] ; ;+001 MAY BE ANY LEGAL FILENAME TO WHICH THE OUTPUT WILL ;+001 BE WRITTEN. IF NOT SPECIFIED, OUTPUT WILL BE WRITTEN ;+JGD TO THE USER'S TERMINAL. IF OUTPUT IS TO OTHER ;+001 THAN A TERMINAL (I.E., A FILE OR LP:) THE OUTPUT WILL ;+001 PRECEDED BY THE COMMAND LINE. MULTIPLE COMMANDS TO ;+001 THE SAME OUTPUT FILE (OR LP:) WILL BE DELIMITED BY A ;+001 LINE OF ASTERISKS. ;2.01 FILE OUTPUT IS SPOOLED TO THE PRINTER UNLESS /-SP IS GIVEN ;2.01 EXPLICITLY. ;2.01 ADD /AP TO APPEND TO AN EXISTING FILE. ;+001 ; MAY BE ANY LEGAL RSX-11M FILESPEC, AND MAY HAVE ; *-FILE NAMES. IF A * IS USED, THE VERSION DEFAULTS ; TO * AUTOMATICALLY. FOR EXAMPLE, X.MAC, TEST.*, *.PLI. ; ; MAY BE ANY STRING WITH THE FOLLOWING RESTRICTIONS: ; 1) EMBEDDED BLANKS AND TABS WILL BE IGNORED. ; 2) THE CHARACTERS ',', '=', '[', ']', '/', ':' AND ';' ; CANNOT BE USED IN THE STRING SINCE THEY ARE ; TREATED AS SPECIAL CHARACTERS BY THE COMMAND ; STRING INTERPRETER. ;2.01 THESE RESTRICTIONS ARE LIFTED IF THE STRING IS PLACED IN QUOTES (") ;2.01 /WI:n may be used to specify a "wild character", which matches ;2.01 any single character. n is the ASCII code, in octal, e.g. /WI:45 ;2.01 specifies the percent sign (%). Default: no wildcard, which can be ;2.01 reset if switches are latched, by /WI:0. ;2.01 ;2.01 /SE:string lists those lines which DO contain string ;2.01 /NE:string lists those which DO NOT contain string ;2.01 ;2.01 /LA latches current switches (default /-LA) ;2.01 /LN lists line numbers (default /LI) ;2.01 /FI lists file names (default /FI) ;2.01 /CM lists command line (default /CM, unless O/P to TI:) ;2.01 /CO:l:h matches on columns l to h only (whole line is still displayed) ;2.01 /LI:l:h matches on lines l to h of each file only ;2.01 /FL:flgchr print whole file, flagging lines which do/don't match with ;2.01 character whose ASCII code is in argument (default *) ;2.03 /MC matches case of alphabetics exactly (default /MC) ;2.03 /EF:n end file search after n (non-)matches (default /EF:infinity) ;2.03 /ES:n end search after grand total of n (non-)matches (default /ES:infinity) ;2.03 /FF:n lists (non-)matching line, and next n (default /FF:0) ;2.01 ;2.01 Default output is TI: if no '=', LP.LST if '='. Default input filetype ;2.01 is .TXT. ; ; WRITTEN: 3-AUG-78, -0.0.0-, BRUCE C. WRIGHT ; MODIFIED: ; VERIFIED: ; ; +001 MAY 1979 RAY FRENCH CHANGED OUTPUT QIO'S TO RECORD I/O ; AND ADDED OUTPUT FILESPEC. MINOR ; MODIFICATIONS TO OUTPUT TO IMPROVE ; READABILITY. ; +002 MAY 1979 RAY FRENCH ADDED LINE NUMBERS TO OUTPUT. ; ; JGD1 MARCH 1980 J. DOWNWARD FIXED BUG CAUSED BY TRANSFERING ; FROM IAS TO 11M($CBDMB DOES NOT SAVE ; R2.) ; JGD2 MODIFIED TO SUPPORT BIG BUFFERING ; RSX11M STYLE RATHER THAN MULTI- ; BUFFERING. ; JGD3 FIXED BUG WITH OVERWRITING FILE ; HEADER ON WILDCARD SEARCHES. ; JGD4 IF NO DEVICE SPECIFIED IN , ; OUTPUT DEFAULTS TO SY: ; ; 2.01 NOV 82 C J Doran Updates for RSX V4:- ; Error messages in lower case ; Exit with status ; Allow key string in quotes, to get ; around restriction on keys including ; space, =, etc. ; + ; Add default spool switch to output file ; Add switches: /AP /SP /LA /WI /CO /FI ; /CM /LN /FL ; Close O/P with truncation or spool. ; Use normal RSX output file handling ; between command lines: i.e. instead of ; appending to an existing output file, ; always close the current one at the start ; of each line. ; Allow more than one input file spec. ; Make code more efficient. ; If sequenced file use F.SEQN, not COUNT ; Ignore FORTRAN & COBOL carriage ctrl bytes ; Use default filename blocks to set devices ; to SY:, and default filetypes. ; Do both input and output in locate mode. ; Allow 160.-col command line. ; 2.02 CJD 21-Apr-83 ; If output is (default) TI:, attach it so ^O will work ; ; 2.03 CJD 25-Jul-85 ; Add /EF:n, /ES:n, /FF:n, /LI:l:h /MC. ; Sort into data and code PSECTs. ; Use PIP-like wildcard opening, see below. ; Prompt GREP>, not GRE>. ; Default /WI to /WI:45 = '%'. ; ; 2.04 CJD 25-Sep-86 ; Correct runaway when line to be printed is zero length (/SE:""/-LN). ; Correct memory overwrite when source line > LINLEN -- it seems that ; GET$ doesn't report this, unless it has to do a move. ; Move SWORD into RW data (was in RO!). ; ; This calls the wildcard handling routines from PIP. The code is taken ;2.03 ; from (redundant) utility TRUNC on the Spring 81 RSX SIG tape, ;2.03 ; directory [300,110], submitted by Jim Downward. ;2.03 ; This requires PIPUTL.OLB from the RSX distribution kit. If you don't ;2.03 ; have this (e.g. running on a VAX with the RSX AME), disable the ;2.03 ; following symbol, which will put back the original code, at the cost ;2.03 ; of proper handling of ;0 and ;-1 version numbers, and wild UICs. ;2.03 ; Note: wild UIC's don't seem to work on a VAX anyway, even in PIP. ;2.03 PIPWLD=0 ;2.03 ;- ; .MCALL QIOW$,DIR$ .MCALL GCMLB$,GCML$,CSI$,CSI$1,CSI$2,CSI$SW,CSI$SV,CSI$ND .MCALL FINIT$,FSRSZ$,FDBDF$,FDOP$A,CLOSE$,OFID$R,GET$ .MCALL FDBF$R,FDRC$R,FDOP$R,NMBLK$,FDBF$A,FDRC$A .MCALL FHDOF$,FDOF$L,NBOFF$ .MCALL FDAT$A,NMBLK$,OPEN$W,PUT$ ;+001 ; ; MULTI-BLOCK COUNT(BIG BUFFERING) ; JGD2 ; ; JGD2 MBCT = 2. ; JGD2 ; ;2.01 Set exit status to EX$ERR if any error is detected. .MACRO ERRMSG MSG .NCHR $$$, JSR R0,$TYPE .WORD $$$ .ASCII "MSG" .EVEN MOV #EX$ERR,EXSTAT .ENDM .PSECT RWDATA,RW,D ;2.03 FHDOF$ DEF$L ; DEFNE FILE HEADER OFFSETS NBOFF$ DEF$L ; DEFINE NAME BLOCK OFFSETS LOCALLY ; COMMAND LINE MACROS AND DATA BLOCKS GCLBLK: GCMLB$ 1,GRE,HEADER,2,,162. CSI$ .EVEN CSIBLK: .BLKB C.SIZE ; CSI BLOCK .EVEN .PSECT RODATA,RO,D ;2.03 SWTABL: CSI$SW SE,SW.SE,SWORD,SET,,SVTABL CSI$SW NE,SW.NE,SWORD,CLEAR,,SVTABL ;2.01 /NE:string = /-SE:string CSI$SW WI,SW.WI,SWORD,SET,,WITABL ;2.01 /WI:char CSI$SW SP,SW.SP,SWORD,SET,NEG ;2.01 /SPool output CSI$SW AP,SW.AP,SWORD,SET,NEG ;2.01 /APpend to existing file CSI$SW LA,SW.LA,SWORD,SET,NEG ;2.01 /LAtch current switches + filetype CSI$SW CM,SW.CM,SWORD,SET,NEG ;2.01 /CM list command line CSI$SW FI,SW.FI,SWORD,SET,NEG ;2.01 /FI list filename(s) CSI$SW LN,SW.LN,SWORD,SET,NEG ;2.01 /LN list line numbers CSI$SW CO,SW.CO,SWORD,SET,,COTABL ;2.01 /CO:lo:hi column selection CSI$SW LI,,SWORD,SET,,LITABL ;2.03 /LI:lo:hi lines selection CSI$SW FL,SW.FL,SWORD,SET,NEG,FLTABL ;2.01 /FLag match/no match lines CSI$SW EF,0,SWORD,SET,NEG,EFTABL ;2.03 /EF:n exit file after n matching lines CSI$SW ES,0,SWORD,SET,NEG,ESTABL ;2.03 /ES:n exit after n matching lines CSI$SW FF,0,SWORD,SET,NEG,FFTABL ;2.03 /FF:n CSI$SW MC,40,MACASE,CLEAR,NEG ; /MC CSI$ND SVTABL: CSI$SV ASCII,STRBUF,STRLEN CSI$ND WITABL: CSI$SV OCTAL,WILDCH,2 ;2.01 Wild character specification CSI$ND ;2.01 CSI$ND ;2.01 COTABL: CSI$SV DECIMAL,LOCOL,2 ;2.01 Lo column specification CSI$SV DECIMAL,HICOL,2 ;2.01 High column CSI$ND LITABL: CSI$SV DECIMAL,LOLINE,2 ;2.03 Lo line specification CSI$SV DECIMAL,HILINE,2 ;2.03 High line CSI$ND FLTABL: CSI$SV OCTAL,FLGCHR,2 ;2.01 Flag character specification CSI$ND EFTABL: CSI$SV DECIMAL,ENDF,2 ;2.03 End file after n matches CSI$ND ESTABL: CSI$SV DECIMAL,ENDS,2 ;2.03 End command after n matches CSI$ND FFTABL: CSI$SV DECIMAL,FOLLOW,2 ;2.03 List n following lines CSI$ND PROMPT: .ASCII <15><12>"GREP>" ; Extended prompt string ;2.03 PRLEN=.-PROMPT ;2.03 .EVEN ;2.03 .PSECT RWDATA,RW,D ;2.03 SWORD: .WORD SW.SP!SW.CM!SW.FI!SW.LN ; Default switches ;2.04 SW.SE = 000001 ;SE - SELECT STRING (must be bit 0) SW.NE = 000001 ;NE - list line which no NOT contain string ;2.01 SW.LA = 100000 ;LA - Latch current switches (must be bit 15) ;2.01 SW.SP = 000002 ;SP - Spool ;2.01 SW.DE = 000004 ; Delete output (internal use only) ;2.01 SW.WI = 000010 ;WI - specify wild character ;2.01 SW.CO = 000020 ;CO - specify columns to search ;2.01 SW.FL = 000040 ;FL - flag lines with/without matches ;2.01 SW.CM = 000400 ;CM - list command line ;2.01 SW.LN = 001000 ;LN - list line numbers ;2.01 SW.FI = 002000 ;FI - list files ;2.01 SW.AP = 000200 ;AP - Append (must be bit 7) ;2.01 LINLEN = 132. ; File line length ;2.01 HEADER: .BLKB 162. LINBUF: .BLKB LINLEN+10. ; MUST USE DIFFERENT BUFFER BECAUSE ; JGD3 ; THE FILE STRING WILL GET OVERWRITTEN ; JGD3 INPLIN: .BLKB LINLEN ;2.01 Input line buffer .EVEN .IF NDF PIPWLD ;2.03 STAT: .WORD 0 ; BUFFER FOR STATISTICS BLOCK .WORD 0 .WORD 0 WLDFLG: .WORD 0 ; FLAG FOR WILD CARDS .ENDC ;2.03 MCHFLG: .WORD 0 ;2.01 Match flag -- used with /FL FLGCHR: .WORD '* ;2.01 Match flag character WILDCH: .WORD 0 ;2.01 Wild character -- default none LOCOL: .WORD 0 ;2.01 Lo column number HICOL: .WORD LINLEN ;2.01 Hi column number LOLINE: .WORD 0 ;2.03 Lo line number HILINE: .WORD 177777 ;2.03 Hi line number FOLLOW: .WORD 0 ;2.03 No of following lines to list after match FOLLPR: .WORD 0 ;2.03 Count of following lines being printed MATCHF: .WORD 0 ;2.03 Count of no of matching lines in this file ENDF: .WORD 177777 ;2.03 End file after n matches MATCHS: .WORD 0 ;2.03 Count of no of matching lines in this command ENDS: .WORD 177777 ;2.03 End command after n matches MACASE: .WORD 0 ;2.03 Set to 40 to not match case EXSTAT: .WORD EX$SUC ;2.01 Exit status -- default success ; I/O MACROS AND DATA BLOCKS FDOF$L FSRSZ$ MBCT+1,,RWDATA ; SET UP FOR BIG BUFFERING ; 2.03 FDB: FDBDF$ ; START OF INPUT FDB FDBF$A ,MBCT*512.,2 ;2.01 Double-bufferred FDRC$A FD.PLC,INPLIN,LINLEN ;2.01 Locate mode, buffer INPLIN .IF DF PIPWLD FDOP$A 1,CSIBLK+C.DSDS .IFF FDOP$A 1,CSIBLK+C.DSDS,DEFINP DEFINP: NMBLK$ ,TXT,0,SY,0 ;2.01 Default filename .ENDC LINFLG: .WORD 0 STRBUF: .BLKB 80. STRLEN = .-STRBUF ; FDB1: FDBDF$ ;+001 - FDB FOR OUTPUT FILE FDRC$A FD.PLC,LINBUF,LINLEN+10. FDAT$A R.VAR,FD.CR ;+001 FDOP$A 3,CSIBLK+C.DSDS,DEFOUT ;+001 .EVEN COMMD: .WORD 0 ;+001 - POINTER FOR START OF COMMAND COUNT: .BLKW 1 ;+002 - LINE COUNTER .PSECT RODATA,D,RW ;2.03 DEFOUT: NMBLK$ LP,LST,0,SY,0 ;2.01 Default filename SY:LP.LST ASTER: .BYTE 12 ;+001 - LINE OF ASTERISKS FOR OUTPUT .REPT 10 ;+001 .ASCII /**********/ ;+001 .ENDR ;+001 TINAM: .ASCII /TI:/ ; OUTPUT BY DEFAULT TO TI: ; 2.01 .EVEN .PSECT CODE,RO,I ;2.03 ; ; READ AND DECODE THE COMMAND LINE ; GREP: FINIT$ ; INITIALIZE FSR START: JSR PC,CLOSEO ;2.01 Close output (if an old one open) GCML$ #GCLBLK,#PROMPT,#PRLEN ;2.03 Get command line BCS 10$ ; ERROR? MOV #HEADER,R1 ;+001 - POINT TO COMMAND LINE MOV GCLBLK+G.CMLD,R2 ;+001 - SIZE IN R2 1$: CMPB #' ,(R1)+ ;+001 - SEARCH FOR A BLANK BEQ 2$ ;+001 SOB R2,1$ ;+001 MOV #HEADER,COMMD ;+001 - NO BLANKS, SO POINT TO START BR 3$ ;CONTIN ;+001 2$: MOV R1,COMMD ;+001 - SAVE THE POINTER 3$: JMP CONTIN ; NO ERROR, SO SKIP AROUND 10$: CMPB #GE.IOR,GCLBLK+G.ERR ; I/O ERROR? BNE 20$ ; NO ERRMSG BR EXIT ;2.01 THIS IS FATAL 20$: CMPB #GE.OPR,GCLBLK+G.ERR ; OPEN ERROR? BNE 30$ ; NO ERRMSG BR START ; RE-DO CMD LINE 30$: CMPB #GE.MDE,GCLBLK+G.ERR ; MAX @ DEPTH? BNE 40$ ; NO ERRMSG BR START 40$: CMPB #GE.BIF,GCLBLK+G.ERR ; SYNTAX ERROR? BNE 50$ ; NO ERRMSG BR JSTART ; RE-START PGM 50$: CMPB #GE.EOF,GCLBLK+G.ERR ; END-OF-FILE? BEQ EXIT ; YES ERRMSG EXIT: JSR PC,CLOSEO ;2.01 Close output file MOV EXSTAT,%0 ;2.01 Load exit status JMP $EXST ;2.01 Exit with it SERR: ERRMSG JSTART: JMP START ; CONTIN: .IIF NDF PIPWLD, CLR WLDFLG ; ASSUME NO WILDCARDS TO START WITH TST ; IS ANYTHING TYPED? BEQ JSTART ;2.01 No, get another line 1$: CSI$1 #CSIBLK,GCLBLK+G.CMLD+2,GCLBLK+G.CMLD ; CHECK SYNTAX BCS SERR ; ERROR IN SYNTAX FOUND TST ; JUST IN CASE A BUNCH OF SPACES FOLLOWED ; BY A ^Z WERE TYPED, CHECK TO BE SURE >0 ; PARSED CHARACTER IS IN THE CSIBLK BEQ EXIT ;2.01 Yes, exit CLR MATCHS ;2.03 Clear grand total of (mis-)matches CLR MACASE ;2.03 Match case exactly BIS #SW.DE,SWORD ;2.01 Temporarily flag delete O/P and TST bit 15 BMI 21$ ;2.01 to see if switches latched MOV #SW.SP!SW.CM!SW.FI!SW.LN!SW.DE,SWORD ;2.01 Unless latched, default switches CLRB STRBUF ; NUL THE STRING BUFFER MOV #'%,WILDCH ;2.01 Set wild character to '%' .IF DF PIPWLD MOV #^RTXT,DN+N.FTYP ;2.01 Reset input filetype .IFF MOV #^RTXT,DEFINP+N.FTYP ;2.01 Reset input filetype .ENDC CLR LOCOL ;2.01 Search columns 1 MOV #LINLEN,HICOL ;2.01 to end of line CLR LOLINE ;2.03 and lines 1 (0 will do) MOV #177777,HILINE ;2.03 to infinity (65535) MOV #177777,ENDF ;2.03 Set end file match count MOV #177777,ENDS ;2.03 and end line count MOV #'*,FLGCHR ;2.01 Flag character (if used) is '*' CLR FOLLOW ;2.03 No following lines shown 21$: ; DECODE THE COMMAND LINE AND OPEN OUTPUT FILE ; MOV #SWTABL,CSIBLK+C.SWAD ;2.01 Set up switch table pointer MOV #TINAM,CSIBLK+C.DEVD+2 ; DEFAULT OUT TO TI: ; JGD MOV #3,CSIBLK+C.DEVD ;2.01 3-byte string MOVB #CS.OUT,CSIBLK+C.TYPR ; Expect an output file BITB #CS.EQU,CSIBLK+C.STAT ; WAS AN EQUAL SIGN SEEN? BNE 3$ ;2.02 Yes, get O/P file name MOV #IO.ATT,QIOW+Q.IOFN ;2.02 No, O/P will be TI: DIR$ #QIOW ;2.02 Attach to it MOV #IO.WVB,QIOW+Q.IOFN ;2.02 Reselect standard write function BR 30$ ;2.02 Go open TI: 3$: JSR PC,CSI2 ;2.01 - DECODE THE OUTPUT FILE MOVB #CS.INP,CSIBLK+C.TYPR ;2.01 Change fetch type to input 30$: FDOP$R #FDB1,,,,#FO.WRT ;2.01 Set up O/P file, default write new file TSTB SWORD ;2.01 But is append set (bit 7)? BPL 40$ ;2.01 No, go open FDOP$R ,,,,#FO.APD ;2.01 Yes, change to re-open for append 40$: JSR PC,.OPEN ;2.01 Open file in required mode NXTINP: JSR PC,CSI2 ;2.01 - DECODE THE INPUT FILE BIC #SW.DE,SWORD ;2.01 OK, don't delete O/P (even if empty) CONT: BITB #FD.TTY,FDB1+F.RCTL ;+001 - WRITING TO TTY ? BNE 10$ ;+001 - IF SO, SKIP ASTERISKS AND COMMAND BIT #SW.CM,SWORD ;2.01 Print command line? BEQ 10$ ;2.01 No, omit again MOV #FDB1,%0 ;2.01 Load FDB pointer for (possibly) 2 PUT$'s TST FDB1+F.NRBD ;+001 - WAS FILE JUST OPENED ? BEQ 1$ ;+001 - THEN FORGET ASTERISKS PUT$ ,#ASTER,#81. ;+001 - WRITE LINE OF ASTERISKS 1$: PUT$ ,COMMD,GCLBLK+G.CMLD ;+001 - AND PRINT COMMAND 10$: ;+001 ; NOW CHECK TO SEE IF WILD CARDS ARE SPECIFIED ; .IF DF PIPWLD FDOP$R #FDB,,#CSIBLK+C.DSDS ;2.03 Reload dataset des, FDB address to R0 CALL ENOPEN ;2.03 Initialise file open BCS OPNERR ;2.03 Failed CALL ENEXT ;2.03 OK, Get the file BCC OPEN ;2.03 OK, open file OPNERR: CALL FERR ;2.03 Issue error message BR RSTART ; START ;2.03 Repeat .IFF MOV #CSIBLK+C.STAT,R0 ; GET ADDRESS OF STATUS WORD BITB #CS.WLD,(R0) ; ANY WILD CARDS BEQ 5$ ; IF EQ, NO WILD CARDS INC WLDFLG ; SET WILDCARD FLAG 5$: MOV #FDB,R0 ; FDB ADRESS IN R0 MOV #FDB+F.FNB,R1 ; FNB ADDRESS IN R1 MOV #CSIBLK+C.DSDS,R2 ; DATASET POINTER IN R2 MOV #DEFINP,%3 ;2.01 Default filename block in %3 (sets SY:) CALL .PARSE ; PARSE THE FDB BCC 20$ ; ALL OK SO SKIP ERROR MESSAGE CALL FERR ; ERROR (FCS) FOUND JMP START ; AND RE-START. 20$: TST WLDFLG ; WILDCARD OPERATION? BEQ RETURN ; IF EQ NO BIS #NB.SVR, ; YES, SO SET THE FLAG BIT ; TO INSURE ANY VERSION WILL BE OPENED RETURN: CALL .FIND ; FIND THE FILE BCS OPNERR ; IF CARRY SET, ERROR TST WLDFLG ; IS THIS A WILD CARD GREP? BEQ OPEN ; IF EQ NO, SO GO DIRECTLY TO OPEN FILE CMP , ; DO WE HAVE A NEW FILE? BEQ RETURN ; NO, TRY AGAIN RET1: MOV , ; SAVE INDEX POINTER MOV , ; SAVE STATUS BR OPEN ; TRY AND OPEN FILE OPNERR: CMPB #IE.NSF,FDB+F.ERR ; IS IT NO SUCH FILE? BEQ 5$ ; YES 3$: CALL FERR ; NO, IT MUST BE AN FCS ERROR BR RSTART ;START ; AND RE-START. 5$: TST WLDFLG ; IS THIS A WILDCARD OPERATION? BEQ 3$ ; NO, NSF IS NOT NORMAL ; YES, NSF IS NORMAL. CLR ; RESET INDEX POINTER .ENDC ;2.03 MORINP: BITB #CS.MOR,CSIBLK+C.STAT ;2.01 Any more input files? BEQ RSTART ;START ;2.01 No, restart .IF DF PIPWLD MOV FDB+F.FNB+N.FTYP,DN+N.FTYP ;2.01 Yes, copy filetype .IFF MOV FDB+F.FNB+N.FTYP,DEFINP+N.FTYP ;2.01 Yes, copy filetype .ENDC JMP NXTINP ;2.01 for next input list entry RSTART: JMP START ; AND BACK FOR MORE ; ; OPEN THE FILE AND LOOK AT IT. ; OPEN: CLR LINFLG ; CLEAR HEADER PRINT FLAG. FDBF$R #FDB,,#<512.*MBCT> ; USE BIG BUFFERING OFID$R ; OPEN THE FILE BY ID BCC LOOKA ; FILE OPENED WITHOUT ERRORS CALL FERR ; PRINT FILE ERROR MOVB FDB+F.ERR,%0 ;2.01 Load error code into a register for efficiency CMPB #IE.PRI,%0 ; DID WE PERHAPS HAVE A PRIVLEGE VIOLATION? ; IF SO IGNORE IT AND CONTINUE BECAUSE FILES ; MAY BE ENTERED FROM ANOTHER DIRECTORY BEQ NXT ; PRIVILEGE VIOLATION - DON'T TRY TO OPEN CMPB #IE.VER,%0 ; PARITY ERROR ON DEVICE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.BBE,%0 ; BAD BLOCK ON DEVICE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.FHE,%0 ; FATAL HARDWARE ERROR? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.BCC,%0 ; BLOCK OR CRC ERROR? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.LCK,%0 ; LOCKED FROM WRITE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.WAC,%0 ; ACCESSED FOR WRITE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.CKS,%0 ;HEADER CHECKSUM FAILURE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.RER,%0 ; DEVICE READ ERROR? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.SNC,%0 ; FID, FILE NUMBER CHECK? BEQ NXT ; YES CMPB #IE.SQC,%0 ; FID, SEQUENCE CHECK? BEQ NXT ; YES CMPB #IE.CLO,%0 ; NOT PROPERLY CLOSED? BEQ NXT ; YES CMPB #IE.BHD,%0 ; BAD FILE HEADER? BEQ NXT ; YES CMPB #IE.EXP,%0 ; EXPIRATION DATE ? BEQ NXT ; YES JMP START ; SOMETHING WORSE - GIVE UP. NXT: JMP NEXT ;+001 LOOKA: CLR COUNT ;+002 - CLEAR LINE COUNTER CLR MATCHF ;2.03 Clear (non-)matches counter LOOK: CLR MCHFLG ;2.01 Clear match on this line flag 1$: INC COUNT ;+002 - INCREMENT LINE COUNTER CMP COUNT,HILINE ;2.03 Passed highest line? BLOS 2$ ;2.03 JMP EOFILE ;2.03 Yes, done 2$: GET$ #FDB ; Get record ;2.04 BCS 21$ ; Error, branch ;2.04 CMP FDB+F.NRBD,#LINLEN ; GET$ says OK, but was line too long? ;2.03 BLOS 23$ ; No, all OK to continue ;2.04 MOV #LINLEN,FDB+F.NRBD ; Yes, truncate line ;2.04 MOVB #IE.RBG,FDB+F.ERR ; Set up error code ;2.04 21$: CMPB FDB+F.ERR,#IE.RBG ; Error. Just record too long? ;2.04 BEQ 22$ ; Yes, can continue from that ;2.04 JMP FILER1 ; No, fatal ;2.04 22$: CALL FERR ; Just report line too long ;2.04 23$: CMP COUNT,LOLINE ;2.03 Below low line? BLO 1$ ;2.03 Just get another if so MOV FDB+F.NRBD+2,R2 ; GET THE START OF THE BUFFER IN R2. MOV FDB+F.NRBD,R3 ; AND LENGTH OF BUFFER. BITB #FD.FTN!FD.PRN,FDB+F.RATT ;2.01 Check for FORTRAN or COBOL c-ctrl BEQ 3$ ;2.01 OK if neither CMPB (%2)+,-(%3) ;2.01 Skip 1 byte for FORTRAN BITB #FD.PRN,FDB+F.RATT ;2.01 BEQ 3$ ;2.01 CMPB (%2)+,-(%3) ;2.01 and 2 for COBOL ("print" file) 3$: CMP %3,HICOL ;2.01 Buffer long enough to reach hi column? BLE 4$ ;2.01 No, search to end of buffer MOV HICOL,%3 ;2.01 Yes, stop search at specified hi column 4$: ADD %2,R3 ;2.01 Point to last byte required ADD LOCOL,%2 ;2.01 Set first column (default 1, dec done in CSI2) 5$: MOV R2,-(SP) ; SAVE BUFFER POINTER. MOV #STRBUF,R4 ; GET STRING ADDR MOV #STRLEN,R5 ; AND LENGTH 10$: TSTB (R4) ; AT END OF DATA? BEQ 15$ ; YES CMP R2,R3 ; OVER TOP OF BUFFER? BHIS 12$ ; 20$ ;2.03 CMPB (R2)+,(R4)+ ; CORRECT BYTE? BEQ 14$ ;2.01 Yes, look for next CMPB -1(%4),WILDCH ;2.01 No, allow wild char to match anything BEQ 14$ ;2.03 OK, match ; If /-MC, see if this is just a mismatch on alphabetic case. ;2.03 BITB MACASE,-1(R2) ;2.03 /LC, and bit 6 set? BEQ 12$ ;2.03 No, neither, no match CMPB -1(R2),#'a ;2.03 Make sure it really was a letter BLO 12$ ; 20$ ;2.03 No, no match CMPB -1(R2),#'z ;2.03 BLOS 13$ ;2.03 12$: BR 20$ ;2.03 13$: MOVB -1(R2),-(SP) ;2.03 Copy the LC letter BICB #40,(SP) ;2.03 Convert to UC CMPB (SP)+,-1(R4) ;2.03 Do chars match now? BNE 20$ ; NO 14$: SOB R5,10$ ; AND LOOP OVER THE STRING. ; Emerging at 15$ means we have a match. Print it if /SE = /-NE is set 15$: MOV (SP)+,R2 INC MCHFLG ;2.01 Note we have a match (set SW.SE in MCHFLG) INC MATCHF ;2.03 Count matches in file INC MATCHS ;2.03 and grand total MOV FOLLOW,FOLLPR ;2.03 Reset following lines count BIT #SW.SE!SW.FL,SWORD ;2.01 Print matches or all? BEQ 19$ ;2.03 No, go look at next 151$: TST LINFLG ; PRINTED FILE NAME? BNE 16$ ; YES BIT #SW.FI,SWORD ;2.01 No, do we want it printed? BEQ 16$ ;2.01 No, don't print CALL PRTFIL ; NO -- PRINT IT. INC LINFLG ; SIGNAL LINE PRINTED. 16$: MOV FDB1+F.NRBD+2,R0 ;2.01 O/P buffer address in R0 CLR %2 ;2.01 Clear length of line BIT #SW.LN,SWORD ;2.01 Print line numbers? BEQ 171$ ;2.01 No, omit MOV COUNT,R1 ;+002 - LINE NUMBER IN R1 CMPB FDB+F.RTYP,#R.SEQ ;2.01 But if records are sequenced BNE 17$ ;2.01 MOV FDB+F.SEQN,%1 ;2.01 use sequence number instead 17$: MOV #^B10111000001010,R2 ;2.01 5 chars decimal, unsigned, blank fill JSR PC,$CBTA ;+002 - CONVERT COUNT AND PUT IN BUFFER MOVB #HT,(R0)+ ;2.01 Tab MOV #6,%2 ;2.01 Note 6 bytes loaded BIT #SW.FL,SWORD ;2.01 Printing all lines? BEQ 171$ ;2.01 No, omit flag character ;2.01 Print flag character if (MCHFLG=1 AND /SE) OR (MCHFLG=0 AND /-SE) ;2.01 i.e. bit 0 of MCHFLG= bit 0 of SWORD, i.e. BIT 0 of sum is clear. ADD SWORD,MCHFLG ;2.01 Form sum ROR MCHFLG ;2.01 Shift out bit 0 BCS 170$ ;2.01 No flag if bits differ MOVB #' ,(%0)+ ;2.01 Else load space MOVB FLGCHR,(%0)+ ;2.01 and flag char CMPB (%2)+,(%2)+ ;2.01 Note 2 more bytes 170$: MOVB #HT,(%0)+ ;2.01 Have another tab INC %2 ;2.01 Count that too 171$: MOV FDB+F.NRBD+2,R1 ;+002 - GET I/P BUFFER ADDRESS ADD FDB+F.NRBD,R2 ;+002 - ADD BYTE COUNT BITB #FD.FTN!FD.PRN,FDB+F.RATT ;2.01 Check for FORTRAN or COBOL c-ctrl BEQ 175$ ;2.01 OK if neither CMPB (%1)+,-(%2) ;2.01 Skip 1 byte for FORTRAN BITB #FD.PRN,FDB+F.RATT ;2.01 But was it COBOL? BEQ 175$ ;2.01 No, branch CMPB (%1)+,-(%2) ;2.01 Yes, make it 2 for COBOL ("print" file) 175$: MOV R2,-(SP) ;+002 - SAVE BYTE COUNT BEQ 181$ ;2.04 Don't runaway if blank line 18$: MOVB (R1)+,(R0)+ ;+002 - ADD RECORD TO BUFFER SOB R2,18$ ;+002 181$: PUT$ #FDB1,,(SP)+,FILERR ;+001 - PRINT IT ; Finish this command line after grand total of n (non-)matches if /ES:n given. ; Stop searching file after n (non-)matches if /EF:n given. 19$: CMP MATCHS,ENDS ;2.03 Finish line after n matches? BLO 191$ ;2.03 No, continue CLOSE$ #FDB ;2.03 Yes, close input file TST (SP)+ ;2.03 Purge stack JMP START ;2.03 End now 191$: CMP MATCHF,ENDF ;2.03 End file after this (nth) match? BLO 30$ ; LOOK ;2.03 No, repeat TST (SP)+ ;2.03 Yes, purge stack BR EOFILE ;2.03 and exit like end-of-file ; Emerging at 20$ means we don't have a match (yet). Keep trying unless reached ; end of record, when print if /NE = /-SE is on (bit clear). 20$: MOV (SP)+,R2 ; RECOVER BUFFER POINTER. INC R2 ; POINT TO NEXT POSITION. CMP R2,R3 ; OVER TOP OF WHOLE BUFFER? BHIS 26$ ;2.03 JMP 5$ ;2.03 NO, NOT YET. 26$: DEC FOLLPR ;2.03 Printing a following line? BPL 151$ ;2.03 Yes, go do it CLR FOLLPR ;2.03 No, reset following lines count to 0 BIT #SW.FL,SWORD ;2.01 Yes, printing all, with flags? BNE 151$ ;2.01 Yes, do so BIT #SW.NE,SWORD ;2.01 No, displaying non-matches? BEQ 151$ ;2.01 Yes if bit clear, go print 30$: JMP LOOK ; NO, LOOK AT NEXT RECORD. FILERR: TST (SP)+ ; POP OFF RETURN ADDR FILER1: CMPB F.ERR(R0),#IE.EOF ; IS IT EOF? BEQ EOFILE ;2.03 NO -- ERROR CALL FERR ; SIGNAL ERROR EOFILE: CLOSE$ #FDB ;2.03 CLOSE THE FILE. BCC NEXT ; FILE COULD BE OPENED AND CLOSED CALL FERR ; FILE COULD EITHER NOT BE OPENED ; OR CLOSED JMP START ; AND RE-START .IF DF PIPWLD ;2.03 NEXT: TSTB ENFLAG ;2.03 Wildcards to process? BEQ 15$ ;2.03 No, look further on command line CALL ENEXT ;2.03 Look for another wild file BCS 10$ ;2.03 Branch if error JMP OPEN ;2.03 OK, go open it 10$: CMPB F.ERR(R0),#IE.NSF ;2.03 Failed, No such file? BNE 20$ ; OPNERR ;2.03 No, a real error 15$: JMP MORINP ;2.03 Yes, no more wild files 20$: JMP OPNERR ;2.03 .IFF ;2.03 NEXT: TST WLDFLG ; IS THIS A WILDCARD OPEN? BGT 10$ ; YES, SO SKIP OVER JMP MORINP ; NO ERRORS, SO CHECK FOR MORE 10$: MOV #FDB,R0 ; FDB ADDRESS IN R0 MOV #FDB+F.FNB,R1 ; FNB ADDRESS IN R1 MOV , ; RESET FOR .FIND MOV , ; JMP RETURN ; AND LOOP SOMEMORE .ENDC ;2.03 PRTFIL: MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) BR FERR1 FERR: DEC EXSTAT ;2.01 Change exit status from success(1) to warning(0) BEQ 10$ ;2.01 Unless it wasn't success INC EXSTAT ;2.01 When leave it alone 10$: MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;SAVE R2 MOV R3,-(SP) ; SAVE R3 MOV #M.FCS,R1 ; ADDR OF FCS MSG MOV #L.FCS,R2 ; LENGTH OF FCS MSG CALL .PRFCS ; PRINT FCS MSG FERR1: MOV #DEVMSG,R1 ; POINT TO DEVICE MSG MOVB #12,(R1)+ ;+001 - PUT IN A LINE FEED MOV #40.,R0 ;GET MAX LENGTH. MOV CSIBLK+C.DEVD,R2 ; GET DEVICE SPEC LEN BLE 12$ ; NONE? MOV CSIBLK+C.DEVD+2,R3 ; GET DEVICE SPEC ADDR 10$: MOVB (R3)+,(R1)+ ; MOVE IN DEVICE SPEC DEC R0 ; DEC TOTAL SPACE BLE 80$ ; SKIP OUT ON 0 SOB R2,10$ ; MOVE IN DEVICE SPEC MOVB #':,(R1)+ ; MOVE IN A : DEC R0 ; DEC TOTAL SPACE BLE 80$ ; SKIP OUT ON 0 12$: MOV CSIBLK+C.DIRD,R2 ; GET UIC SPEC LEN BLE 22$ ; NONE? MOV CSIBLK+C.DIRD+2,R3 ; GET UIC SPEC ADDR 20$: MOVB (R3)+,(R1)+ ; MOVE IN UIC SPEC DEC R0 ; DEC TOTAL SPACE BLE 80$ ; SKIP OUT ON 0 SOB R2,20$ ; MOVE IN ALL OF UIC 22$: MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ; AND R1 MOV #TEMP,R0 ; POINT TO HEADER BUFFER. MOVB #':,(R0)+ ; BASE PTR MOV FDB+F.FNB+N.FNAM,R1 ; CONVERT FNAM TO RAD50 CLR R2 ; CALL $C5TA ; MOV FDB+F.FNB+N.FNAM+2,R1 CALL $C5TA MOV FDB+F.FNB+N.FNAM+4,R1 CALL $C5TA 30$: CMPB #' ,-(R0) ;IS IT A BLANK? BEQ 30$ ;YES INC R0 ; MOV FDB+F.FNB+N.FTYP,R1 BNE 35$ ; PRINT IT IF SPECIFIED CMP R0,#TEMP+1 ;IS THIS THE BEG. OF STRING? BNE 45$ ; NO -- DON'T PRINT THE . 35$: MOVB #'.,(R0)+ ; MOVE IN A . CALL $C5TA ;TYPE FIELD TO ASCII 40$: CMPB #' ,-(R0) ;IS IT A BLANK? BEQ 40$ ;YES INC R0 ; 45$: MOV FDB+F.FNB+N.FVER,R1 ;GET FILE VERSION BEQ 50$ ;NONE? MOVB #';,(R0)+ ;MOVE IN A ';' CLR R2 ; SUPPRESS 0'S CALL $CBOMG ; CONVERT VERSION # 50$: MOV #TEMP+1,R3 ; SAVE ADDR SUB R3,R0 ; COMPUTE LENGTH MOV R0,R2 ;SAVE IN R2 MOV (SP)+,R1 ;RECOVER R1 MOV (SP)+,R0 ;RECOVER R0 60$: MOVB (R3)+,(R1)+ ; MOVE IN FILE DEC R0 ; DEC TOTAL SPACE BLE 80$ ; SKIP OUT ON 0 SOB R2,60$ ; MOVE IN ENTIRE FILE 80$: SUB #DEVMSG,R1 ;COMPUTE LEN OF MSG PUT$ #FDB1,#DEVMSG,R1,FILERR ;+001 - PRINT IT MOV (SP)+,R3 ;RECOVER R3 MOV (SP)+,R2 ; RECOVER R2 MOV (SP)+,R1 ; RECOVER R1 MOV (SP)+,R0 ; RECOVER R0 RTSPC: RTS PC ;2.01 Close output file -- delete, print, or just truncate according to SWORD ;2.01 bit settings. Detach TI: if it was the output file. CLOSEO: BITB #CS.EQU,CSIBLK+C.STAT ;2.02 Explicit output file? BNE 5$ ; Yes, assume it wasn't TI: MOV #IO.DET,QIOW+Q.IOFN ;2.02 Load Detach function DIR$ #QIOW ;2.02 Detach TI:. MOV #IO.WVB,QIOW+Q.IOFN ;2.02 Reselect standard write function 5$: TST FDB1+F.BDB ;2.01 Is output file open? BEQ RTSPC ;2.01 No, just exit MOV #FDB1,%0 ;2.01 Address output FDB BIT #SW.DE,SWORD ;2.01 Delete? BNE 20$ ;2.01 Yes, branch BIT #SW.SP,SWORD ;2.01 Spool? BEQ 10$ ;2.01 No, just close JMP .PRINT ;2.01 Yes, spool 10$: JMP .TRNCL ;2.01 No, close and truncate 20$: JMP .DLFNB ;2.01 Delete O/P on input parse failure $TYPE: MOV (R0)+,QIOW+Q.IOPL+2 ;MOVE IN QIO LENGTH MOV R0,QIOW+Q.IOPL ;AND ADDRESS MOV #QIOW,-(SP) CALL .DIRDL ADD -2(R0),R0 ;ADD IN QIO LENGTH INC R0 ;INC R0 TO GET TO EVEN BOUND. BIC #1,R0 ;CLEAR LOW BIT - RTS TO EVEN BOUND. RTS R0 ;AND RETURN TO CALLER. ; Fetch next file. ; Process switches /SE/NE and /CO if they occur on the current file:- ; For /CO, decrement hi and lo values, and make sure 1=1 BGT 25$ ;2.01 Yes, OK MOV #1,LOCOL ;2.01 No, make it 1 25$: CMP HICOL,LOCOL ;2.01 Make sure hi>=lo BGE 30$ ;2.01 OK if so MOV LOCOL,HICOL ;2.01 Else make them equal 30$: DEC LOCOL ;2.01 Dec lo col to save doing it each line 50$: BIT #SW.WI,SWORD ;2.03 /WI given? BNE 100$ ;2.03 Yes, keep character supplied CLR WILDCH ;2.03 No, clear it for no match 100$: RTS PC ;2.01 Done 200$: TST (SP)+ ;2.01 Purge return address JMP SERR ;2.01 Return abnormally on error ; TERMINAL QIOs QIOW: QIOW$ IO.WVB,3,1,,,,<0,0,40> M.FCS: .ASCII /GRE/ L.FCS = .-M.FCS .EVEN .EVEN ; ERROR MESSAGES DEVMSG: .BLKB 40. .EVEN TEMP: .BLKB 40. .END GREP