Google
 

Trailing-Edge - PDP-10 Archives - BB-H311D-RM - swskit-hacks/find.mac
There are 3 other files named find.mac in the archive. Click here to see a list.
	TITLE	FIND	SUBSTRING SEARCH PROGRAM
	SUBTTL	J. G. ZIMA/JGZ  AUGUST 1980

	SEARCH	MACSYM,MONSYM	;GET SYMBOLS
	SEARCH	ZSUBS		;GET SUBROUTINE PACKAGE
	SALL			;NICE LOOKING MACROS
	.DIRECT	FLBLST		;AND NICE LISTING


;VERSION INFORMATION:


	VMAJOR==2		;MAJOR VERSION LEVEL
	VMINOR==0		;MINOR VERSION LEVEL
	VEDIT==^D55		;EDIT LEVEL
	VWHO==0			;WHO LAST EDITED



;FIND is a substring search program.  The canonical use is to search
;all of the monitor source files for all occurrances of a given symbol.
;FIND is designed to be fast, and reasonably concise to run.  It
;is not intended to ever become full of features which will detract
;from those goals.
;
;ASSEMBLY INSTRUCTIONS:
;
;	@LOAD FIND.MAC
;	@SAVE FIND
;
;RELATED FILES:
;	FIND.MAC	THIS FILE
;	FIND.CTL	CONTROL FILE TO BUILD FIND
;	ZSUBS.UNV	UNIVERSAL FOR COMND/LUUO SUBROUTINES
;	ZSUBS.REL	REQUIRE FILE FOR COMND/LUUO SUBROUTINES
;
	SUBTTL	TABLE OF CONTENTS


;	TABLE OF CONTENTS					  PAGE
;	-----------------					  ----
;
;  1. J. G. ZIMA/JGZ  AUGUST 1980. . . . . . . . . . . . . . . . .   1
;  2. TABLE OF CONTENTS. . . . . . . . . . . . . . . . . . . . . .   2
;  3. REVISION HISTORY . . . . . . . . . . . . . . . . . . . . . .   3
;  4. DEFINITIONS. . . . . . . . . . . . . . . . . . . . . . . . .   7
;  5. ENTRY VECTOR AND INITIALIZATION. . . . . . . . . . . . . . .   8
;  6. THE SIMPLE COMMANDS - HELP . . . . . . . . . . . . . . . . .  10
;  7. RESET COMMAND TO RESET PARAMETERS. . . . . . . . . . . . . .  11
;  8. INFORMATION COMMAND TO TELL PARAMETERS . . . . . . . . . . .  13
;  9. TYPEOUT FORMATTING SELECTION COMMANDS. . . . . . . . . . . .  15
; 10. CHARACTER MATCH CASE SELECTION SETTING . . . . . . . . . . .  16
; 11. FILES COMMAND TO GIVE FILE SPECIFICATION . . . . . . . . . .  17
; 12. STRING COMMAND . . . . . . . . . . . . . . . . . . . . . . .  18
; 13. LIST COMMAND TO SPECIFY OUTPUT FILE AND BEGIN. . . . . . . .  19
; 14. SEARCH ROUTINE . . . . . . . . . . . . . . . . . . . . . . .  21
; 15. SCAN ROUTINE TO SCAN INPUT FILE. . . . . . . . . . . . . . .  23
; 16. INCLUD - ROUTINE TO PRINT A MATCH. . . . . . . . . . . . . .  24
; 17. STRING COMPARISON ROUTINE. . . . . . . . . . . . . . . . . .  25
; 18. NXTFIL ROUTINE TO RETURN NEXT FILE . . . . . . . . . . . . .  26
; 19. MORE ROUTINE TO MAP NEXT FILE SEGMENT. . . . . . . . . . . .  29
; 20. STSINT STATUS INTERRUPT ROUTINE. . . . . . . . . . . . . . .  30
; 21. SKPINT - SKIP FILE INTERRUPT ROUTINE . . . . . . . . . . . .  31
; 22. ILLEGAL MEMORY READ INTERRUPT. . . . . . . . . . . . . . . .  32
; 23. THE DATA AREA. . . . . . . . . . . . . . . . . . . . . . . .  33
	SUBTTL	REVISION HISTORY

;REVISION HISTORY:

;   1	JGZ	7-AUG-80
;		START KEEPING THE REVISION HISTORY NOW THAT AT LEAST 70%
;		OF THE CODE IS IN.
;
;   2	JGZ	10-AUG-80
;		REMOVE SRCDON CONSTRUCT, INSTALL CONTROL-A INTERRUPT.
;
;   3	JGZ	21-AUG-80
;		USE THE NAME "FIND" FOR THE PROGRAM.
;
;   4	JGZ	22-AUG-80
;		MAKE CONTROL-A DO TDEC INSTEAD OF DECOUT.
;
;   5	JGZ	24-AUG-80
;		TRY USING PRELOADING PMAPS TO SEE IF IT HELPS.
;
;   6	JGZ	26-AUG-80
;		SET MATCH COUNTER TO ZERO BEFORE CALLING SEARCH.
;
;   7	JGZ	26-AUG-80
;		CHANGE LISTING FORMAT A BIT, MOVE BLANK LINES.
;
;  10	JGZ	26-AUG-80
;		PUT A TAB IN THE SEPARATOR IN MODULE-NAME-ONLY FORMAT
;		BETWEEN THE FILENAME AND STRING.
;
;  11	JGZ	28-AUG-80
;		ADD MATCHF VARIABLE TO COUNT NUMBER OF FILES WITH MATCHES.
;		ADD SUMMARY LINE TO LIST COMMAND GIVING MATCHC AND MATCHF.
;
;  12	JGZ	12-SEP-80
;		ADD CONTROL-E ABORT OF LIST COMMAND.
;
;  13	JGZ	12-SEP-80
;		ADD THE GIVE COMMAND SO PEOPLE WHO WANT TO CAN SEE EACH
;		FILENAME AS SEARCHED.
;
;  14	JGZ	16-OCT-80
;		MAKE MODULE-NAME-ONLY COUNT UP MATCH FILES IN MATCHF.
;
;  15	JGZ	18-OCT-80
;		HANDLE OFF-LINE FILES IN THE SEARCH LIST MORE GRACEFULLY.
;
;  16	JGZ	16-DEC-80
;		MORE OFF-LINE FILES FIX.  CRLF AFTER MESSAGE.
;
;  17	JGZ	18-DEC-80
;		PRETTY UP PLURAL SYNTAX FOR MATCH COUNT TYPEOUT.
;
;  20	JGZ	1-JAN-80
;		SOME CODE CLEANUP AND START ADDING ^X INTERRUPT.
;
;  21	JGZ	1-JAN-80
;		FINISH REST OF CONTROL-X INTERRUPT HANDLING.  IMPROVE
;		ERROR HANDLING IN NXTFIL FOR SOME RECOVERABLE CASES AND
;		GIVE FILENAME ON MORE UNRECOVERABLE ONES.
;
;  22	JGZ	7-JAN-80
;		BE SURE CONTROL-A AND CONTROL-X ARE TURNED OFF ON CONTROL-E
;		PATH OUT OF THE CODE.
;
;  23	JGZ	9-JAN-80
;		START ADDING STRUCTURES FOR HANDLING FILES LARGER THAN
;		THE INTERNAL BUFFER EVENTUALLY.
;
;  24	JGZ	9-JAN-80
;		HANDLE STRING NUMBER IN SCAN DIFFERENTLY TO REMOVE MULTIPLY.
;		MAKE A FEW OTHER TINY SPEEDUPS IN SCAN.
;
;  25	JGZ	9-JAN-80
;		STRIP CONTROL-V FROM SEARCH STRINGS.
;
;  26	JGZ	11-JAN-80
;		ONE MORE PLACE TO CHANGE P6 USAGE (INCLUD).
;
;  27	JGZ	17-FEB-80
;		PUT NUMBERS ON THE FILES AND STRINGS TO REFER TO LATER.
;
;  30	JGZ	20-FEB-80
;		CLEAN UP THE LISTING A BIT
;
;  31	JGZ	24-FEB-80
;		TURN PRINT TO PRINT. IN INCLUDE.  MATCH STRING WAS NOT
;		BEING OUTPUT, GETTING "0(P6)" INSTEAD.
;
;  32	JGZ	10-MAR-81
;		MARK OJFN CLOSED AFTER CLOSING IT IN LSTFIN.
;
;  33	JGZ	12-MAR-81
;		INSTALL TEMPORARY CODE TO JUST INFORM AND SKIP FILES TOO
;		LARGE FOR INTERNAL BUFFER.
;
;  34	JGZ	18-MAR-81
;		DO SETSN TO SEE ACCUMULATED SUBSYSTEM STATISTICS.
;
;  35	JGZ	22-JAN-82
;		CONVERT TO USE ZSUBS.  BEGIN MAJOR VERSION TWO.
;
;  36	JGZ	26-JAN-82
;		TEXT MACRO IS NOW IN ZSUBS TOO.  USE LERROR IN A FEW PLACES.
;
;  37	JGZ	26-JAN-82
;		ADD OMIT COMMAND TO COMPLEMENT GIVE COMMAND.  ADD RESET
;		COMMAND OPTIONS.
;
;  40	JGZ	27-JAN-82
;		START ADDING THE BIG FILE SEGMENTATION CODE.  UPDATE THE
;		HELP TEXT.
;
;  41	JGZ	27-JAN-82
;		PUT THE OFFLINE FILE SKIPPED TYPEOUTS UNDER THE "GIVE"
;		REPORTING MODE BIT.  COUNT FILES ABORTED AND SKIPPED FOR STATS.
;		PRINT THE TOTAL ON THE FINAL STATUS LINE.
;
;  42	JGZ	28-JAN-82
;		MAKE USE OF THE NEW TYPJFN/PRTJFN ZSUBS LUUOS TO OUTPUT
;		FILESPECS.
;
;  43	JGZ	28-JAN-82
;		FINISH THE BIG FILE SEGMENTATION CODE AND TURN IT ON WITH
;		A SMALL SEGMENT SIZE FOR DEBUGGING.  NOTE - THE ADJUSTMENTS
;		NEEDED ARE VERY MESSY, AND ALSO THE DESTINATION CROCK FOR
;		THE EXTEND INSTRUCTION MUST BE RE-INITIALIZED!
;
;  44	JGZ	28-JAN-82
;		MUST STORE FILENAME STRINGS IF WANT TO CONTINUE TO USE
;		THEM...
;
;  45	JGZ	30-JAN-82
;		PERFORMANCE IMPROVEMENT - DON'T COUNT LINES IF DOING
;		MODULE-NAME-ONLY REPORTING.
;		(MEASURES ABOUT 10 PER CENT BETTER ON CPU TIME)
;
;  46	JGZ	2-FEB-82
;		FIX AWFUL BUG WHERE MATCH CHARACTER IS LAST CHARACTER OF
;		SEGMENT AND P1 FIXUP IS NOT RIGHT.
;
;  47	JGZ	3-FEB-82
;		CLEAN UP LISTING, DEFINE SEGMENTATION SYMBOLS SO NOT AS MUCH
;		BUGGY EXPRESSION ARITHMETIC, REMOVE BYTCNT VARIABLE, NEW
;		TABLE OF CONTENTS.
;
;  50	JGZ	24-FEB-82
;		TEST PERIOD OVER, PUT BUFFER SIZE BACK TO LARGE VALUE.
;
;  51	JGZ	13-APR-82
;		CHANGE IDIVI OF SEGBY TO IDIV FROM MEMORY.
;
;  52	JGZ	9-JAN-84
;		HANDLE THE CASE OF THE ILLEGAL MEMORY READ FROM FILES
;		WITH HOLES IN THEM.
;
;  53	JGZ	9-APR-84
;		USE VI%DEC FOR DECIMAL VERSION NUMBER.
;
;  54	JGZ	23-APR-84
;		ADD CASE-OF-CHARACTERS COMMAND TO SET IF UPPER AND
;		LOWER CASE ARE THE SAME.
;
;  55	JGZ	10-SEP-84
;		FIX CALCULATION OF FBYTCT FOR NON-7-BIT FILES.  REPORTED
;		BY BOB LONGO (RAL).
;
	SUBTTL	DEFINITIONS

;DEFAULT PARAMETERS:


	MAXFIL==^D16		;MAXIMUM NUMBER OF JFNS TO ALLOW
	MAXSTR==^D16		;MAXIMUM NUMBER OF STRINGS TO ALLOW
	STRSIZ==^D8		;SIZE OF A STRBUF ENTRY

	BUFFER==10000		;BUFFER STARTS AT PAGE 10
	BUFSIZ==670		;MAX PAGES TO MAP
	SEGSIZ==BUFSIZ		;SEGMENTATION PARAMETERS
	SEGPG==BUFSIZ		;NUMBER OF PAGES IN SEGMENT
	SEGWD==SEGPG*PGSIZ	;NUMBER OF WORDS IN SEGMENT
	SEGBY==SEGWD*5		;NUMBER OF BYTES IN SEGMENT



;FLAGS:


	FL%MNO==1B0		;MODULE-NAMES-ONLY OUTPUT FORMAT IF SET
	FL%FNO==1B1		;FILE NAME HAS BEEN OUTPUT
	FL%GEF==1B2		;GIVE EVERY FILENAME WHILE SEARCHING
	FL%NOX==1B3		;CRITICAL REGION - DON'T TAKE ^X NOW
	FL%BIG==1B4		;FILE IS TOO BIG FOR INTERNAL BUFFER
	FL%PCC==1B5		;PRESERVE CHARACTER CASE FOR COMPARE


;CONSTANTS:

	INTCHN==0		;CHANNEL FOR ^E INTERRUPT
	STSCHN==1		;CHANNEL FOR STATUS (^A) INTERRUPT
	SKPCHN==2		;CHANNEL FOR SKIP FILE (^X) INTERRUPT

	PGSIZ==1000		;SIZE OF A PAGE
	PGSFT==^D9		;NUMBER OF BITS FOR PAGE SHIFTING

	RES.ST==1B35		;RESET SEARCH STRINGS CODE
	RES.FN==1B34		;RESET FILENAMES LIST CODE
	RES.LM==1B33		;RESET LISTING MODE CODE
	RES.RM==1B32		;RESET REPORTING MODE CODE
	SUBTTL	ENTRY VECTOR AND INITIALIZATION

EVEC:	JRST	FIND		;START
	JRST	REEN		;REENTER
	BYTE	(3)VWHO(9)VMAJOR(6)VMINOR(18)VI%DEC+VEDIT ;VERSION



FIND:	RESET			;CLEAR EVERYTHING
	SETZ	F,		;CLEAR ALL FLAGS
	$INIT			;INITIALIZE ZSUBS PACKAGE
	TYPE	<FIND %>	;TYPE BANNER AND VERSION
	VERSIO	EVEC+2		;OUTPUT VERSION NUMBER
	TYPE	<

>				;AND A CRLF
	DMOVE	T1,[EXP	'FIND  ','FIND  ']
	SETSN			;SET OUR SYSTEM NAME TO GATHER STATISTICS
	 ERJMP	.+1		;FORGET ERRORS HERE
	SETZM	FILCNT		;NO FILES GIVEN YET
	SETZM	STRCNT		;NO STRINGS GIVEN YET

REEN:	MOVE	P,[IOWD PDLSIZ,PDL]	;SET UP A STACK
	SETZM	OJFN		;CLEAR OUTPUT JFN
	MOVE	T1,[1,,STSINT]	;SETUP CONTROL-A TRANSFER ADDRESS
	MOVEM	T1,CHNTAB+STSCHN ;IN THE CHANNEL PSI TABLE
	MOVE	T1,[1,,SKPINT]	;SETUP CONTROL-X TRANSFER ADDRESS
	MOVEM	T1,CHNTAB+SKPCHN ;IN THE CHANNEL PSI TABLE
	MOVE	T1,[1,,IRDINT]	;SETUP ILLEGAL MEMORY READ ADDRESS
	MOVEM	T1,CHNTAB+.ICIRD ;IN THE CHANNEL PSI TABLE
	MOVX	T1,.FHSLF	;FOR US
	MOVX	T2,1B<STSCHN>+1B<SKPCHN>+1B<.ICIRD> ;CHANNELS FOR ^A
				; AND ^X  AND ILL MEM READ INTERRUPTS
	AIC			;SET THEM UP


NEWCMD:	HRROI	T1,[ASCIZ/FIND>/] ;SET PROMPT
	MOVEM	T1,CMDBLK+.CMRTY ;IN COMND BLOCK
	MOVEI	T1,NEWPAR	;AND SET THE
	HRRM	T1,CMDBLK+.CMFLG ;REPARSE ADDRESS ALSO
	PARSE	[FLDDB. .CMINI] ;INITIALIZATION FUNCTION
	MOVEM	P,SAVEP		;SAVE STACK FOR REPARSING
	JRST	NEWPAR		;AND PARSE A NEW COMMAND

PARERR:	JRST	REEN		;REPARSE ADR-1=WHERE TO GO ON ERROR
NEWPAR:	MOVE	P,SAVEP		;RESTORE THE STACK
	SKIPE	T1,JFNTMP	;UNLOAD ANY LEFTOVER JFNS
	RLJFN			; FROM REPARSING,...
	 ERJMP	.+1		;DON'T WORRY ABOUT ERRORS
	SETZM	JFNTMP		;AND MARK THE "JFN STACK" EMPTY
	PARSE	[FLDDB. (.CMKEY,,CMDTAB)] ;PARSE FROM COMMAND TABLE
	MOVE	T2,0(T2)	;GET ADDRESS OF ROUTINE
	CALL	0(T2)		;CALL IT
	JRST	NEWCMD		;AND GET A NEW COMMAND




;TABLE OF COMMANDS:


CMDTAB:	CMDLEN,,CMDLEN			;HEADER
	AA	CASE-OF-CHARACTERS,.CASE ;SET WHETHER UPPER==LOWER
	AA	COMPLETE-LISTING,.COMP	;COMPLETE LISTING FORMAT
	AA	EXIT,.EXIT		;EXIT COMMAND
	AA	FILES,.FILES		;FILE SPECIFICATION
	AA	GIVE,.GIVE		;GIVE ALL FILENAMES SEARCHED
	AA	HELP,.HELP		;TYPE HELP MESSAGE
	AA	INFORMATION,.INFO	;INFORMATION ABOUT PARAMETERS
	AA	LIST,.LIST		;LIST COMMAND TO START
	AA	MODULE-NAMES-ONLY,.MODULE ;ONLY LIST SUCCESSES
	AA	OMIT,.OMIT		;OMIT GIVING SEARCH FILENAMES
	AA	PUSH,.PUSH		;PUSH TO A NEW EXEC
	AA	RESET,.RESET		;RESET PARAMETERS
	AA	STRING,.STRING		;STRING SPECIFICATION
	AA	TAKE,.TAKE		;TAKE COMMANDS FROM FILE

	CMDLEN==.-CMDTAB-1		;NUMBER OF COMMANDS
	SUBTTL	THE SIMPLE COMMANDS - HELP

;THE "HELP" COMMAND.

.HELP:	NOISE	(WITH COMMANDS)	;DO GUIDEWORDS
	CONFRM			;CONFIRM THE LINE
	TYPE.	HLPTXT		;TYPE THE HELP TEXT
	RET			;AND DONE


HLPTXT:	TEXT	<

FIND  is a program to search lists of files for lists of  strings and
to report on matches, for instance, to find all references to a given
symbol in a group of modules.

The commands are:

CASE-OF-CHARACTERS	Specify whether the case of characters is important
			for a match.  Default is IGNORED, so uppercase and
			lower case map together.
COMPLETE-LISTING	Specify complete listing format, which consists
			of the filename, string, line number and line which
			contains the match string for each match.
EXIT			Exit the program.
FILES			Specify a possibly wild file specification to be
			searched.  A maximum of 16 such specifications may
			be given.
GIVE			Give the names of all files as they are searched.
HELP			Type this text.
INFORMATION		List the currently active parameters: Files to
			search, search strings, listing format.
LIST			Specify the file to list to (default is TTY:) and
			begin the search process.  A Control-A character
			will output the name of the file currently being
			searched.  A Control-E character will abort the
			search.  A Control-X will abort the current file.
MODULE-NAMES-ONLY	Specifies quick listing format.  Output listing
			consists only of the filename of any file containing
			a match along with the first match string in that
			file.  Searching of the file stops after the first
			match occurs.  This listing format is faster and
			more compact than the complete listing.
OMIT			Do not give the names of files as they are searched.
PUSH			Transfer control to an EXEC in an inferior fork.
RESET			Reset parameters: files, strings, listing format.
			No longer done implicitly after every LIST command.
STRING			Specify a search string.  Limit is 39 characters.
			A maximum of 16 strings may be specified.
TAKE			Take commands from the given file.


[End of FIND.HLP]

>
	SUBTTL	RESET COMMAND TO RESET PARAMETERS

;HERE TO PROCESS THE RESET COMMAND TO CLEAR FILENAMES, STRINGS, FLAGS SET.

.RESET:	NOISE	(PARAMETER)	;GUIDEWORDS
	PARSE	[FLDDB.	(.CMKEY,,RESTAB,,<ALL>)] ;GET WHAT OPTION
	HRRZ	P1,0(T2)	;FETCH THE APPROPRIATE FLAGS
	CONFRM			;CONFIRM THE LINE

RESET0:
	SETOM	T1		;FOR UNMAPPING
	MOVE	T2,[.FHSLF,,BUFFER_-PGSFT]
	MOVX	T3,PM%CNT+SEGPG ;FLUSH ALL THE PAGES
	PMAP			;SO CLOSES WILL WORK
	 ERJMP	LOSE

;SEARCH STRINGS

	TXNE	P1,RES.ST	;RESET STRINGS?
	 SETZM	STRCNT		; YES, ZERO NUMBER OF STRINGS GIVEN

;FILES

	TXNN	P1,RES.FN	;RESET FILES?
	 JRST	RESET2		; NO, GO ON

	SETZM	FILCNT		;MARK NONE IN LIST
	SETZM	FILJFN		;AND MARK NONE IN USE

;LISTING MODE

RESET2:	TXNE	P1,RES.LM	;LISTING MODE?
	 TXZ	F,FL%MNO	; YES, CLEAR MODULE NAME ONLY FLAG

;GIVE FILENAMES MODE

	TXNE	P1,RES.RM	;FILENAME REPORTING MODE?
	 TXZ	F,FL%GEF	; YES, CLEAR GIVE EVERY FILE FLAG

	RET			;AND ALL DONE

;TABLE OF RESET OPTIONS

RESTAB:	RESLEN,,RESLEN
	AA	ALL,RES.ST!RES.FN!RES.LM!RES.RM
	AA	FILES,RES.FN
	AA	LISTING-MODE,RES.LM
	AA	REPORTING-MODE,RES.RM
	AA	STRINGS,RES.ST
	RESLEN==.-RESTAB-1
	SUBTTL	INFORMATION COMMAND TO TELL PARAMETERS

;HERE TO PROCESS THE INFORMATION COMMAND TO REGURGITATE THE INPUTS.

.INFO:	NOISE	(ABOUT PARAMETERS) ;GUIDEWORDS
	CONFRM			;CONFIRM THE COMMAND

	TYPE	<
Files to search specified are:
>				;LEADIN
	MOVN	P1,FILCNT	;-COUNT
	HRLZS	P1		;TO LH FOR AOBJN
	JUMPE	P1,INFO2	;GO IF NONE
INFO1:	MOVEI	T2,1(P1)	;BUILD A NUMBER
	TDEC	T2,6		;OUTPUT THE NUMBER
	TYPE	<  >		;A COUPLE OF SPACES
	MOVEI	T2,0(P1)	;NUMBER
	IMULI	T2,STRSIZ*5	;POINT TO STRING START
	TYPE.	FILLST(T2)	;TYPE IT OUT
	TYPE	<
>				;FINISH LINE WITH CRLF
	AOBJN	P1,INFO1	;AND LOOP FOR ALL

INFO2:	TYPE	<
Strings to search for are:
>				;LEADIN
	MOVN	P1,STRCNT	;-COUNT
	HRLZS	P1		;TO LH FOR AOBJN
	JUMPE	P1,INFO4	;GO IF NONE
INFO3:	HRRZ	T1,P1		;STRING NUMBER
	MOVEI	T2,1(T1)	;AND START WITH ONE FOR TYPEOUT
	TDEC	T2,6		;OUTPUT THE NUMBER
	TYPE	<  >		;A COUPLE OF SPACES
	IMULI	T1,STRSIZ	;STRING NUMBER TIMES BLOCKSIZE
	TYPE.	STRBUF(T1)	;TYPE THE STRING
	TYPE	<
>				;FINISH LINE WITH A CRLF
	AOBJN	P1,INFO3	;AND LOOP FOR ALL

	;...
INFO4:	TXNN	F,FL%MNO	;CHECK LISTING FORMAT
	TYPE	<
Listing format is complete listing.
>
	TXNE	F,FL%MNO	;FOR EITHER CASE
	TYPE	<
Listing format is module name only on matches.
>
	TYPE	<
Filenames will>			;LEADIN
	TXNN	F,FL%GEF	;GIVING ALL NAMES?
	TYPE	< not>		;YES
	TYPE	< be typed for each file as searched.
>				;FINISH FILENAME TYPEOUT MODE
	TXNN	F,FL%PCC	;CHECK CHARACTER CASE
	TYPE	<
Character case will be ignored.

>
	TXNE	F,FL%PCC	;OTHER SENSE
	TYPE	<
Character case will be preserved.

>
	RET			;ALL DONE
	SUBTTL	TYPEOUT FORMATTING SELECTION COMMANDS

;HERE TO PROCESS THE MODULE-NAMES-ONLY COMMAND.  SETS FL%MNO SO THAT
;THE OUTPUT FORMAT AND SEARCH ARE QUICKER.

.MODULE: NOISE	(LISTING FORMAT) ;GUIDEWORDS
	CONFRM			;CONFIRM THE COMMAND
	TXO	F,FL%MNO	;TURN ON THE FLAG TO SAY SO
	RET			; AND ALL DONE



;HERE TO PROCESS THE COMPLETE-LISTING COMMAND. CLEARS FL%MNO SO THAT
;ALL THE OUTPUT AND SEARCHING ARE DONE.

.COMP:	NOISE	(LISTING FORMAT) ;GUIDEWORDS
	CONFRM			;CONFIRM THE COMMAND
	TXZ	F,FL%MNO	;CLEAR THE FLAG
	RET			; AND ALL DONE HERE



;HERE TO PROCESS THE GIVE COMMAND.  SETS FL%GEF SO THAT ALL NAMES ARE
;TYPED AS THE FILES ARE PROCESSED.

.GIVE:	NOISE	(ALL FILENAMES AS THEY ARE SEARCHED) ;GUIDEWORDS
	CONFRM			;CONFIRM THE INTENT
	TXO	F,FL%GEF	;SET THE BIT
	RET			; AND WE ARE DONE



;HERE TO PROCESS THE OMIT COMMAND.  CLEARS FL%GEF SO THAT ALL NAMES ARE
;NOT TYPED AS THE FILES ARE PROCESSED.

.OMIT:	NOISE	(ALL FILENAMES AS THEY ARE SEARCHED) ;GUIDEWORDS
	CONFRM			;CONFIRM THE COMMAND
	TXZ	F,FL%GEF	;CLEAR THE FLAG
	RET			; AND ALL DONE
	SUBTTL	CHARACTER MATCH CASE SELECTION SETTING

;HERE TO PROCESS THE CASE-OF-CHARACTERS COMMAND.  SETS OR CLEARS
;THE FL%PCC FLAG TO INDICATE PRESERVATION OF CHARACTER CASE IN
;MATCH STRINGS.

.CASE:	NOISE	(IN MATCH STRINGS IS TO BE) ;GUIDEWORDS
	PARSE	[FLDDB. (.CMKEY,,CASTAB,,<IGNORED>)] ;PARSE FROM TABLE
	MOVE	P1,0(T2)	;FETCH VALUE
	CONFRM			;CONFIRM THE COMMAND
	TXZ	F,FL%PCC	;ASSUME DEFAULT
	SKIPE	P1		; SEE WHAT WAS SAID
	 TXO	F,FL%PCC	;PRESERVE CASE
	RET			;ALL DONE


;TABLE OF CASE OPTIONS

CASTAB:	CASLEN,,CASLEN		;HEADER
	AA	IGNORED,0	;DEFAULT TO IGNORE
	AA	PRESERVED,1	;PRESERVE CASE
	CASLEN==.-CASTAB-1	;LENGTH
	SUBTTL	FILES COMMAND TO GIVE FILE SPECIFICATION

;HERE TO PROCESS THE FILES COMMAND TO GET ANOTHER JFN FOR FILES TO
;SEARCH AND PUT IT ON THE LIST.

.FILES:	NOISE	(TO SEARCH)	;GUIDEWORDS
	MOVX	T2,GJ%OLD!GJ%IFG!GJ%FLG	;EXISTS, WILD, RETURN FLAGS
	MOVEM	T2,JFNBLK+.GJGEN ;SET UP GTJFN FLAGS
	HRROI	T2,[ASCIZ/*/]	;SETUP DEFAULTS FOR
	MOVEM	T2,JFNBLK+.GJNAM ;FILENAME
	MOVEM	T2,JFNBLK+.GJEXT ;EXTENSION
	PARSE	[FLDDB. (.CMFIL,,,,<*.*.0>)] ;GET THE INPUT FILE
	MOVEM	T2,JFNTMP	;SAVE THE JFN
	CONFRM			;CONFIRM THE LINE
	MOVE	T1,FILCNT	;GET THE COUNT
	CAILE	T1,MAXFIL	;TOO MANY?
	 ERROR	<Too many files> ;YUP
	IMULI	T1,STRSIZ*5	;TIMES THE SPEC SIZE
	HRROI	T1,FILLST(T1)	;POINT TO BUFFER
	MOVE	T2,JFNTMP	;GET THE JFN AGAIN
	MOVX	T3,JS%SPC	;FULL SPEC
	JFNS			;SAVE THE STRING
	 ERJMP	LOSE
	MOVE	T1,T2		;JFN BACK
	RLJFN			;DON'T NEED IT ANYMORE
	 ERJMP	.+1		;LET THEM PILE UP IF FAILS
	SETZM	JFNTMP		;MARK NO JFN TO FLUSH
	AOS	FILCNT		;BUMP THE COUNT
	RET			; AND WE ARE DONE
	SUBTTL	STRING COMMAND

;HERE TO PROCESS THE STRING COMMAND TO GET A SEARCH STRING AND PUT
;IT IN THE STRING LIST.

.STRING: NOISE	(TO SEARCH FOR)	;GUIDEWORDS
	PARSE	[FLDDB. (.CMTXT,CM%SDH,,<Substring to locate>)]
	MOVE	P1,[POINT 7,ATMBUF] ;POINT TO THE INPUT
	MOVE	P2,STRCNT	;NUMBER IN USE
	IMULI	P2,STRSIZ	;TIMES SIZE
	ADDI	P2,STRBUF	;PLUS START OF BUFFER
	HRLI	P2,(POINT 7,)	;AND LH BUILDS BYTE POINTER
	MOVX	P3,STRSIZ*5-1	;MAX CHARACTERS IN STRING

STRIN1:	ILDB	T1,P1		;GET NEXT BYTE
	JUMPE	T1,STRIN3	;DONE ON NULL
	CAIE	T1,.CHCNV	;REMOVE ANY CONTROL-V'S
	CAIN	T1,.CHCRT	;IGNORE CARRIAGE RETURNS
	 JRST	STRIN1		;IN STRING
	CAIN	T1,.CHLFD	;OR LINEFEED
	 JRST	STRIN3		;TERMINATE
	TXNE	F,FL%PCC	;CONSIDER CHARACTER CASE?
	 JRST	STRIN2		; YES
	CAIL	T1,"a"		;NO, TURN LOWERCASE TO UPPER
	CAILE	T1,"z"		;WITH USUAL CODE
	 SKIPA
	SUBI	T1,"a"-"A"
STRIN2:	IDPB	T1,P2		;STORE BYTE
	SOJG	P3,STRIN1	;LOOP FOR 39 CHARS AT MOST
STRIN3:	MOVEI	T1,0		;END WITH A NULL
	IDPB	T1,P2		;TO TERMINATE STRING

	CONFRM			;CONFIRM THE COMMAND
	SKIPN	P3		;STRING TOO LONG?
	 WARN	<Search string truncated to 39 characters>
	MOVE	T1,STRCNT	;CURRENT NUMBER
	CAILE	T1,MAXSTR	;SPACE LEFT?
	 ERROR	<Maximum number of strings already in use>
	CAIE	P3,STRSIZ*5-1	;BY THE BY, WAS THERE ANYTHING THERE?
	AOS	STRCNT		;YES, COUNT THE STRING
	RET			;AND ALL DONE
	SUBTTL	LIST COMMAND TO SPECIFY OUTPUT FILE AND BEGIN

;HERE TO PROCESS LIST COMMAND.  SPECIFY OUTPUT FILESPEC AND BEGIN THE
;PROCESSING OF THE SEARCH.

.LIST:	NOISE	(OUTPUT TO FILE) ;GUIDEWORDS
	PARSE	[FLDDB. (.CMOFI,,,,<TTY:>)] ;SETUP AND GET FILESPEC
	MOVEM	T2,JFNTMP	;SAVE JFN IN JFN STACK
	NOISE	(AND BEGIN)	;MORE GUIDEWORDS
	CONFRM			;CONFIRM THE COMMAND
	SKIPN	FILCNT		;ANY FILES TO DO?
	 ERROR	<No files specified>
	SKIPN	STRCNT		;ANY STRINGS TO DO?
	 ERROR	<No search strings specified>
	MOVE	T1,JFNTMP	;GET THE JFN
	MOVEM	T1,OJFN		;MAKE IT THE OUTPUT JFN
	SETZM	JFNTMP		;MARK JFN STACK EMPTY

	MOVE	T1,OJFN		;OUTPUT FILE JFN
	MOVX	T2,OF%WR+FLD(7,OF%BSZ) ;ASCII MODE
	OPENF			;DO OPEN
	 ERJMP [LERROR	<Cannot open output file>]
	SETZM	MATCHC		;ZERO COUNT OF MATCHES
	SETZM	MATCHF		; AND NUMBER OF FILES WITH MATCHES
	SETZM	FSKIP		; AND NUMBER SKIPPED OR ABORTED
	SETABT	LSTABT		;SET UP THE CONTROL-E INTERRUPT
	CALL	SEARCH		;GO DO IT
LSTFIN:	CLRABT			;CLEAR ANY ACTIVE CONTROL-E CHANNEL
	MOVX	T1,.TICCA	;NO MORE FILES TO DO
	DTI			;SO CLEAR CONTROL-A
	 ERJMP	LOSE
	MOVX	T1,.TICCX	;AND ALSO
	DTI			;CLEAR CONTROL-X
	 ERJMP	LOSE
	;...

;NOW PRINT OUT THE TERMINATION FILES STATISTICS (FALL THROUGH)

	PRINT	<
Total of >			;START SUMMARY LINE
	DECOUT	MATCHC		;DO NUMBER OF MATCHES
	PRINT	< match>	;MORE TEXT
	MOVE	T1,MATCHC	;GET COUNT
	CAIE	T1,1		;CHECK THE SINGULAR CASE
	PRINT	<es>		;HANDLE PLURAL
	PRINT	<, >		;MORE TEXT
	DECOUT	MATCHF		;DO NUMBER OF FILES WITH MATCHES
	PRINT	< file>		;TEXT
	MOVE	T1,MATCHF	;GET FILE COUNT
	CAIE	T1,1		;CHECK FOR THE SINGULAR CASE
	PRINT	<s>		;DO PLURAL
	PRINT	< contained matches, >
	DECOUT	FSKIP		;DO THE NUMBER SKIPPED
	PRINT	< files skipped or aborted
>				;FINAL TEXT
	SKIPE	T1,OJFN		;GET THE OUTPUT JFN
	CLOSF			; AND CLOSE IT
	 ERJMP [LERROR	<Cannot close output file>]
	SETZM	OJFN		; MARK IT CLOSED
	RET			;DONE, PRESERVE FILES, STRINGS,...




;HERE ON CONTROL-E ABORT OF LIST COMMAND

LSTABT:	MOVX	T1,.PRIOU	;CLEAR THE
	CFOBF			;OUTPUT IN PROGRESS
	 ERJMP	LOSE
	WARN	Command aborted
	MOVE	P,SAVPSI	;PUT STACK BACK TO KNOWN VALUE
	CALLRET	LSTFIN		;FINISH UP THE NORMAL WAY
	SUBTTL	SEARCH ROUTINE

;SEARCH - ROUTINE TO DO THE ACTUAL SEARCH.  ENTERED WITH THE PARAMETERS
;ALREADY SETUP FOR THE SEARCH.
;RETURNS  +1:	ALWAYS, ON COMPLETION OF THE SEARCH

SEARCH:	MOVE	T1,[CTBL,,XTBL]	;COPY OVER THE BASE TABLE
	BLT	T1,XTBL+^D63	;WITH NORMAL BLT
	MOVE	T1,[.CHLFD,,.CHLFD+1] ;ASSUME NO BREAK ON LF
	TXNN	F,FL%MNO	;MODULE-NAME-ONLY?
	 TXO	T1,<100000,,0>	; NO - SET OPCODE TO BREAK ON LF
	MOVEM	T1,XTBL+<.CHLFD/2> ;SET WORD
	MOVN	T1,STRCNT	;NUMBER OF STRINGS
	HRLZS	T1		;AOBJN POINTER
SEARC0:	HRRZ	T2,T1		;OFFSET
	IMULI	T2,STRSIZ	;TIMES SIZE
	MOVE	T3,[POINT 7,STRBUF(T2)] ;POINT AT STRING
	ILDB	T3,T3		;AND GET FIRST BYTE
	MOVE	T2,[POINT 18,XTBL] ;POINT TO TABLE
	MOVE	T4,T3		;COPY CHARACTER
	ADJBP	T4,T2		;UPDATE BYTE POINTER
	ILDB	T2,T4		;GET BYTE
	TXO	T2,100000	;OPCODE TO TERMINATE TRANSLATION
	DPB	T2,T4		;PUT BYTE BACK
	TXNE	F,FL%PCC	;CASE MATTER?
	 JRST	SEARCL		;YES, DON'T CONVERT
	CAIL	T3,"A"		;IF ALPHABETIC, THEN
	CAILE	T3,"Z"		;MUST SET LOWERCASE BYTE ALSO
	 SKIPA
	 JRST [	ADDI	T3,"a"-"A"	;GET LOWERCASE VALUE
		MOVE	T2,[POINT 18,XTBL] ;START OF TABLE
		ADJBP	T3,T2		;POINT TO L/C BYTE
		ILDB	T2,T3		;GET BYTE
		TXO	T2,100000	;SET TERMINATE OPCODE
		DPB	T2,T3		;PUT BYTE BACK
		JRST	.+1]		;CONTINUE INLINE
SEARCL:	AOBJN	T1,SEARC0	;LOOP FOR ALL STRINGS

	SETZM	FILJFN		;ZERO FILJFN SO IT GETS THE FIRST
	MOVE	T1,[.TICCA,,STSCHN] ;SETUP CONTROL-A
	ATI			;TO GO TO STSINT
	 ERJMP	LOSE
SEARCX:	MOVE	T1,[.TICCX,,SKPCHN] ;SETUP CONTROL-X
	ATI			;TO GO EVENTUALLY TO SKPABT
	 ERJMP	LOSE
	MOVEM	P,SAVEPX	;RECORD THE CURRENT STACK POSITION
	;...
	;...
SEARC1:	TXO	F,FL%NOX	;SET CONTROL-X CRITICAL REGION
	CALL	NXTFIL		;SETUP THE NEXT FILE TO DO
	 JRST [	MOVX	T1,.TICCA	;NO MORE FILES TO DO
		DTI			;CLEAR CONTROL-A
		 ERJMP	LOSE
		MOVX	T1,.TICCX	;AND ALSO
		DTI			;CLEAR CONTROL-X
		 ERJMP	LOSE
		RET]			;RETURN

	TXZ	F,FL%NOX!FL%FNO	;END CRITICAL REGION, MARK FILENAME NOT OUTPUT
	TXNE	F,FL%GEF	;DOES USER WANT TO SEE ALL NAMES?
	 JRST [	TYPE	<Searching > ;LEADIN
		TYPJFN	FILJFN,FULL ;YES, GIVE IT TO HIM
		TYPE	<
>				;AND A NEW LINE
		JRST	.+1]	;THEN CONTINUE IN LINE
	MOVEI	T1,1		;FILE STARTS ON LINE ONE
	MOVEM	T1,LINENO	;SO INIT LINE COUNT
	MOVE	P1,FBYTCT	;GET FILE BYTE COUNT
	TXNE	F,FL%BIG	;BIG FILE?
	 MOVX	P1,SEGBY	; YES, USE SEGMENT SIZE INSTEAD
	MOVE	P2,[POINT 7,BUFFER] ;SOURCE BYTEPOINTER
	MOVEM	P2,LINPTR	;SET INITIAL LINE POINTER ALSO
	SETZB	P3,P6		;THESE ACS ARE UNUSED
	DMOVE	P4,[	EXP	5 ;AND SET UP ONE WORD DESTINATION CROCK
			POINT 7,DSTBUF]
	CALL	SCAN		;DO THE SCAN
	JRST	SEARC1		;LOOP TIL DONE WITH ALL


;SKPABT - ROUTINE TO HANDLE THE CONTROL-X SKIP FILE ABORT
;TYPES OUT THE FILENAME, ADJUSTS THE STACK AND CONTINUES

SKPABT:	MOVX	T1,.PRIOU	;WAIT FOR THE
	DOBE			; OUTPUT STREAM TO COMPLETE
	TYPE	<Aborting search of > ;LEADIN TO FILENAME
	TYPJFN	FILJFN,FULL	;TYPE THE FILENAME
	TYPE	<
>				;FINISH THE LINE
	AOS	FSKIP		;COUNT THE FILE
	MOVE	P,SAVEPX	;ADJUST THE STACK,
	JRST	SEARCX		; AND CONTINUE WITH THE NEXT FILE
	SUBTTL	SCAN ROUTINE TO SCAN INPUT FILE

;SCAN - HERE WE USE A MOVST TO SCAN THE INPUT FILE BYTE BY BYTE AND
;HAVE IT BREAK ON LINE FEEDS AND THE FIRST CHARACTER (UPPER OR LOWER
;CASE) OF STRINGS WHICH MAY MATCH THE TARGET KEYWORDS.  ON A BREAK,
;WE THEN DETERMINE WHAT TO DO FROM THERE, DO IT, AND COME BACK TO
;SCAN AGAIN.
;ACCEPTS:
;  P1-P5/	SETUP FOR MOVST INSTRUCTION
;
;	CALL	SCAN
;
;RETURNS  +1:	ALWAYS, AT END OF FILE

SCAN:	EXTEND	P1,[	MOVST	XTBL	;DO THE SCAN
			EXP	0]	;FILL
	 SKIPA				;TERMINATED ON CHARACTER
	JRST [	TXNN	F,FL%BIG	;NEED TO DO MORE?
		 RET			; NO, OUT OF FILE TO PROCESS
		CALL	MORE		;YES, DO THE NEEDED MAP, ADJUSTMENTS
		MOVE	T1,FBYTCT	;FILE BYTE COUNT
		IDIV	T1,[SEGBY]	;NUMBER OF BYTES
		MOVE	P1,T2		;GET REMAINDER IF NOW NON-BIG
		TXNE	F,FL%BIG	;STILL BIG?
		 MOVX	P1,SEGBY	; YES, USE NUMBER OF BYTES IN BUFFER
		JRST	SCAN]		; AND CONTINUE WITH THE SCAN

	LDB	T2,P2		;GET THE TERMINATOR
	CAIN	T2,.CHLFD	;LINE FEED?
	 JRST [	AOS	LINENO	;YES, COUNT IT
		MOVEM	P2,LINPTR ;SAVE POINTER TO START OF LINE
		JRST	SCAN]	; AND CONTINUE

	MOVN	P6,STRCNT	;NUMBER OF STRINGS
	HRLZS	P6		;BUILD AOBJN POINTER
	HRRI	P6,<STRBUF-STRSIZ+1> ;PRESET FOR FIRST STRING
SCAN1:	SETO	T2,		;-1
	ADJBP	T2,P2		;GET ADJUSTED POINTER FOR ILDB
	MOVEM	P1,SCNSVP	;SAVE OLD POINTER IN CASE NO MATCH
	ADDI	P6,<STRSIZ-1>	;POINT TO NEXT STRING
	HRRZ	T1,P6		;COPY ADDRESS
	HRLI	T1,(<POINT 7,0>) ;AND BUILD A BYTE POINTER TO STRING
	CALL	STRCMP		;DO THE STRING COMPARE
	 JRST [	MOVE	P1,SCNSVP ;RESTORE P1 ON MATCH FAILURE
		AOBJN	P6,SCAN1 ;LOOP FOR ALL STRINGS...
		JRST	SCAN]	; AND CONTINUE SCAN WHEN NO MORE
	AOS	MATCHC		;COUNT MATCH
	MOVE	P2,T2		;UPDATE POINTER
	CALL	INCLUD		;A MATCH, GENERATE OUTPUT
	TXNN	F,FL%MNO	;MODULE-NAMES-ONLY?
	AOJA	P1,SCAN		;NO, LOOP, MAKING UP FOR EARLIER ADJBP COUNT
	 RET	 		;YES, ONE OUTPUT IS ENOUGH
	SUBTTL	INCLUD - ROUTINE TO PRINT A MATCH

;INCLUD - HERE TO OUTPUT A MATCH
;
;  P6/		-N,,ADDRESS OF MATCH STRING
;  LINPTR/	BEGINNING OF LINE CONTAINING MATCH

INCLUD:	TXNN	F,FL%MNO	;MODULE-NAMES-ONLY?
	 JRST	INCLUA		;NO
	PRTJFN	FILJFN,FULL	;YES, OUTPUT THE FILENAME
	PRINT	<  	(>	;OPEN PAREN
	PRINT.	0(P6)		;PRINT MATCH STRING
	PRINT	<)
>				;END WITH A CRLF
	AOS	MATCHF		;COUNT THE FILE FOR A MATCH
	RET			;AND DONE

;HERE TO DO THE FULL-BLOWN OUTPUT

INCLUA:	TXOE	F,FL%FNO	;FILE NAME OUTPUT YET?
	 JRST	INCLU1		;YES, JUST DO MATCH STRING
	AOS	MATCHF		;COUNT THE FILE THE FIRST TIME
	PRTJFN	FILJFN,FULL	;OUTPUT THE FILENAME
	PRINT	<

>				;BLANK LINE
INCLU1:	PRINT	<(Line >	;OPEN PAREN
	DECOUT	LINENO		;GIVE LINE NUMBER
	PRINT	<:  >		;DELIMIT
	PRINT.	0(P6)		;PRINT MATCH STRING
	PRINT	<)
>				;CLOSE PAREN
	MOVE	T1,OJFN		;GET OUTPUT JFN (PRINT. NOT GOOD ENOUGH)
	MOVE	T2,LINPTR	;POINT TO START OF LINE
	MOVEI	T3,^D128	;DO THIS MANY CHARS MAX
	MOVEI	T4,.CHLFD	;OR TERMINATE ON LINEFEED
	SOUT			;OUTPUT THE LINE WITH THE MATCH
	 ERJMP	LOSE
	PRINT	<
>				;FINISH WITH BLANK LINE
	RET			;AND DONE FOR NOW
	SUBTTL	STRING COMPARISON ROUTINE

;STRCMP	THIS ROUTINE PERFORMS THE FILE TO TARGET STRING COMPARE.
;
;  T1/	BYTE POINTER TO THE TARGET PATTERN
;  T2/	BYTE POINTER INTO THE INPUT FILE
;
;	CALL	STRCMP
;RETURNS:  +1:	IF THE MATCH IS UNSUCCESSFUL
;	   +2:	IF THE MATCH IS SUCCESSFUL, P1 COUNTED

STRCMP:	ILDB	T3,T1		;GET BYTE FROM PATTERN STRING
	JUMPE	T3,RSKP		;A MATCH IF AT END, SKIP RETURN
	ILDB	T4,T2		;GET BYTE FROM TEST STRING
	SOJL	P1,[TXNN F,FL%BIG	;MORE FILE MAYBE?
		     RET		;NO
		    DMOVEM T1,STRSV2	;SAVE T1,T2
		    CALL MORE		;YES, MAP, ADJUST
		    DMOVE T1,STRSV2	;GET T1,T2 BACK
		    SUBI T2,<SEGWD-PGSIZ> ;ADJUST T2 WORD ADDRESS DOWN
		    ILDB T4,T2		; OTHER ONE ALSO
		    LDB T3,T1		;GET BYTE BACK
		    JRST .+1]		;AND CONTINUE
	TXNE	F,FL%PCC	;CASE MATTER?
	 JRST STRCM1		; YES, SKIP CONVERSION
	CAIL	T4,"a"		;CONVERT OCCURRENCES OF
	CAILE	T4,"z"		; LOWER CASE
	 SKIPA
	SUBI	T4,"a"-"A"	; TO UPPER CASE
STRCM1:	CAMN	T3,T4		;THE COMPARE
	 JRST	STRCMP		;MATCH SO FAR, CONTINUE
	RET			;DIFFERENCE, RETURN NONSKIP
	SUBTTL	NXTFIL ROUTINE TO RETURN NEXT FILE

;NXTFIL - ROUTINE TO RETURN NEXT FILE TO USE.
;ACCEPTS:
;  FILJFN/	CURRENT JFN
;
;	CALL	NXTFIL
;
;RETURNS  +1:	NO MORE FILES TO PROCESS
;	  +2:	NEXT JFN IS IN FILJFN
;
;UNMAPS AND CLOSES CURRENT FILE AND OPENS AND MAPS NEXT.
;STEPS THROUGH FILLST USING VARIABLE FILSTP AS AN INDEX.

NXTFIL:	SKIPN	FILJFN		;SEE IF FILE IS IN USE
	 JRST [	MOVN	T1,FILCNT	;START WITH COUNT
		HRLZ	T1,T1		;BUILD AOBJN POINTER
		MOVEM	T1,FILSTP	;AND SET FILSTP
		HRROI	T2,FILLST	;POINT TO THE FIRST STRING
		MOVX	T1,GJ%SHT+GJ%IFG!GJ%OLD!GJ%FLG ;WHAT TO LOOK FOR
		GTJFN			;GET THE JFN
		 ERJMP	LOSE
		MOVEM	T1,FILJFN	;SAVE THE JFN
		JRST	NXTFLO]		;THEN GO OPEN IT
	SETOM	T1		;-1 TO UNMAP
	MOVE	T2,[.FHSLF,,BUFFER_-PGSFT] ;THE PAGES IN BUFFER
	HRRZ	T3,FSIZE	;NUMBER OF PAGES WE HAVE MAPPED
	TXO	T3,PM%CNT	;COUNT BIT
	PMAP			;UNMAP THE PAGES
	 ERJMP [WARN	<Trouble with file - > ;LEADIN AND
		TYPJFN	FILJFN,FULL ;LET HIM KNOW WHICH ONE
		LERROR	<Cannot unmap file pages>] ;THEN DIE
	HRRZ	T1,FILJFN	;JFN AGAIN
	TXO	T1,CO%NRJ	;DON'T LOSE JFN
	CLOSF			; BUT CLOSE FILE
	 ERJMP [WARN	<Trouble with file - > ;LEADIN AND
		TYPJFN	FILJFN,FULL ;LET HIM KNOW WHICH ONE
		LERROR	<Cannot close input file>] ;THEN DIE
	;...
;NOW STEP THE CURRENT JFN

NXTFI0:	MOVE	T1,FILJFN	;GET THE JFN
	GNJFN			;STEP IT
	 ERJMP [CAIE	T1,GNJFX1	;NO MORE?
		 JRST	LOSE		;SOME OTHER ERROR, CROAK
		MOVE	T1,FILSTP	;GET THE STEP INDEX
		AOBJP	T1,R		;NO MORE AT ALL!
		MOVEM	T1,FILSTP	;RESTORE STEP INDEX
		HRRZS	T1		;GET THE SPEC NUMBER
		IMULI	T1,STRSIZ*5	;TIMES THE SPACE NEEDED
		HRROI	T2,FILLST(T1)	;POINT TO THE STRING
		MOVX	T1,GJ%SHT+GJ%OLD+GJ%IFG+GJ%FLG ;TYPE OF GTJFN
		GTJFN			;GET A JFN ON IT
		 ERJMP	LOSE
		MOVEM	T1,FILJFN	;SET IT (GNJFN RELEASED OLD ONE)
		JRST	.+1]		;AND CONTINUE IN LINE


;OPEN AND MAP THE NEW FILE

NXTFLO:	HRRZ	T1,FILJFN	;GET JFN PART
	MOVX	T2,OF%RD	;OPENING JUST FOR READ
	OPENF			;TRY THE OPEN
	 ERJMP [AOS	FSKIP		;COUNT UP NUMBER SKIPPED
		TXNN	F,FL%GEF	;GIVE ALL FILES MODE?
		 JRST	NXTFI0		; NO, BE SILENT.
		HRRZ	T1,FILJFN	;GET JFN BACK
		MOVE	T2,[1,,.FBCTL]	;WANT TO READ JUST .FBCTL
		MOVEI	T3,T3		;INTO T3 IS FINE
		GTFDB			;READ FDB
		 ERJMP	LOSE
		TXNN	T3,FB%OFF	;OFF-LINE?
		 WARN	<OPENF failed, skipping file > ;NO, GIVE THIS MESSAGE
		TXNE	T3,FB%OFF	;OFF-LINE?
		 WARN	<Off-line file skipped - > ;SAY SORRY
		TYPJFN	FILJFN,FULL	;GIVE THE NAME
		TYPE	<
>					;CRLF THE LINE
		JRST	NXTFI0]		;AND TRY ANOTHER
	;...
	;...
	MOVE	T2,[2,,.FBBYV]	;WORDS TO READ FROM FDB
	MOVEI	T3,P1		;WHERE TO READ THEM
	GTFDB			;READ THEM
	 ERJMP	LOSE
	HRRZM	P1,TFSIZE	;SAVE THE TOTAL FILE SIZE IN PAGES
	MOVE	T1,TFSIZE	;FETCH THE SIZE BACK
	TXZ	F,FL%BIG	;ASSUME NOT BIG
	CAILE	T1,SEGPG	;FILE TOO LARGE?
	 JRST [	TXO	F,FL%BIG ;MARK IT
		SETZM	BIGSEG	;RECORD START OF SEGMENT
		MOVX	T1,SEGPG ;DO A SEGMENT OF SEGPG PAGES
		JRST	.+1]	; AND CONTINUE INLINE
	MOVEM	T1,FSIZE	;SAVE CURRENT MAPPED FILE SIZE
	LOAD	T1,FB%BSZ,P1	;GET THE BYTE SIZE
	CAIE	T1,7		;NICE KOSHER ASCII?
	 JRST [	MOVX	T2,^D36	;CALCULATE NUMBER OF BYTES/WORD
		IDIV	T2,T1	; INTO T2
		ADDI	P2,-1(T2) ;ROUND UP
		IDIV	P2,T2	; AND CONVERT TO NUMBER OF WORDS
		IMULI	P2,^D5	;HENCE TO NUMBER OF ASCII BYTES
		JRST	.+1]	;AND CONTINUE
	MOVEM	P2,FBYTCT	;SAVING BYTE COUNT FOR FILE

	HRLZ	T1,FILJFN	;JFN,,0
	MOVE	T2,[.FHSLF,,BUFFER_-PGSFT] ;INTO BUFFER
	MOVX	T3,PM%CNT+PM%RD+PM%PLD ;TO READ, AND SET PRELOAD BIT
	HRR	T3,FSIZE	;NUMBER OF PAGES TO MAP
	PMAP			;MAP THEM
	 ERJMP [LERROR	<Cannot map input file>]

	RETSKP			;RETURN WITH NEXT FILE
	SUBTTL	MORE ROUTINE TO MAP NEXT FILE SEGMENT

;MORE - ROUTINE TO MAP THE NEXT SEGMENT OF A FILE WITH FL%BIG SET
;AND ADJUST THE POINTERS TO ACCOMMODATE CHANGES IN CORE ADDRESS.
;LAST PAGE OF BUFFER IS MOVED TO BE THE FIRST.  THIS MAKES THE
;BOLD ASSUMPTION THAT A MATCH STRING IS NOT LONGER THAN A PAGE....
;AND THAT THE LAST LINE STARTS ON THE LAST PAGE, AND THAT MATCH
;LINES DON'T CROSS THE SEGMENT BOUNDARY (THE LAST BEING WRONG).
;DOES ALL THE MESSY FIXUPS ON ALL THE VARIABLES IT KNOWS ABOUT.


MORE:	SETOM	T1		;-1 TO UNMAP
	MOVE	T2,[.FHSLF,,BUFFER_-PGSFT] ;THE PAGES IN THE BUFFER
	HRRZ	T3,FSIZE	;GET THE COUNT
	TXO	T3,PM%CNT	;COUNT BIT
	PMAP			;MAP THEM AWAY
	 ERJMP [WARN	<Trouble with file - > ;LEADIN AND
		TYPJFN	FILJFN,FULL ;LET HIM KNOW WHICH ONE
		LERROR	<Cannot unmap file pages>] ;THEN DIE

	MOVEI	T1,SEGPG-1	;SHIFT DOWN BY N-1 PAGES
	ADDM	T1,BIGSEG	;NEW START PAGE ADDRESS FOR SEGMENT
	MOVE	T1,TFSIZE	;GET TOTAL PAGE COUNT
	SUB	T1,BIGSEG	;MINUS LAST START
	CAILE	T1,SEGPG	;STILL TOO BIG?
	 JRST [	MOVEI	T1,SEGPG ;SIZE IS STILL SEGPG
		JRST	MORE0]	;AND CONTINUE
	TXZ	F,FL%BIG	;LAST SEGMENT, DON'T COME HERE AGAIN
MORE0:	MOVEM	T1,FSIZE	;STORE APPROPRIATE SIZE VALUE
	MOVE	T1,BIGSEG	;GET STARTING SEGMENT NUMBER
	HRL	T1,FILJFN	;GET THE SOURCE JFN
	MOVE	T2,[.FHSLF,,BUFFER_-PGSFT] ;GET DESTINATION POINTER
	MOVE	T3,FSIZE	;GET THE NUMBER OF PAGES TO MAP
	TXO	T3,PM%CNT+PM%RD+PM%PLD ;READ N PAGES WITH PRELOADING
	PMAP			;MAP NEXT SEGMENT
	 ERJMP [LERROR	<Unable to map next file segment>]

;NOW ADJUST POINTERS...

	MOVX	T1,-<SEGWD-PGSIZ> ;USE ADDRESS OFFSET TO
	ADDM	T1,LINPTR	;UPDATE POINTER TO LAST LINE

	ADD	P1,[SEGBY-<PGSIZ*5>] ;UPDATE BYTE COUNTER IN P1 FOR ADDED PAGES

	SUBI	P2,<SEGWD-PGSIZ> ;UPDATE POINTER IN P2

	DMOVE	P4,[	EXP	5 ;AND SET UP ONE WORD DESTINATION CROCK
			POINT 7,DSTBUF]

	MOVE	T1,[<SEGBY-<PGSIZ*5>>] ;CALCULATE BYTE OFFSET FOR P1 THAT SCAN
	ADDM	T1,SCNSVP	; SAVES AND UPDATE IT
	RET			;RETURN SUCCESSFULLY FOR MORE FILE
	SUBTTL	STSINT STATUS INTERRUPT ROUTINE

;STSINT - ROUTINE TO HANDLE A STATUS INTERRUPT ON CONTROL-A
;TO TYPE OUT THE NAME OF THE FILE CURRENTLY BEING PROCESSED.

STSINT:	MOVEM	P,PIACS+P	;SAVE THE ACS
	MOVE	P,[0,,PIACS]	; WITH A BLT
	BLT	P,PIACS+16	; TO THE SAVE BLOCK
	MOVE	P,PIACS+P	;REGET A STACK TO USE
	PUSH	P,.JBUUO##	;PUSH UUO LOC SO WE ARE INTERRUPTABLE

	MOVEI	T1,.PRIOU	;WAIT FOR A CHANCE TO
	DOBE			;GET INTO THE OUTPUT
	TYPE	<Working on >	;LEADIN TO FILENAME
	TYPJFN	FILJFN		;TYPE OUT THE FILESPEC WE ARE USING
	TYPE	<, >		;DELIMIT
	TDEC	MATCHC		;GIVE MATCH COUNT
	TYPE	< match>	;MORE TEXT
	MOVE	T1,MATCHC	;GET COUNT
	CAIE	T1,1		;THE SINGULAR CASE?
	TYPE	<es>		;DO PLURALS NICELY
	TYPE	<
>				;FINISH WITH A CRLF

	POP	P,.JBUUO##	;POP UUO LOCATION
	MOVE	P,[PIACS,,0]	;SETUP BLT AND
	BLT	P,P		; RESTORE THE ACS
	DEBRK			;THEN RETURN FROM INTERRUPT
	 ERJMP	LOSE		;FAILED...
	SUBTTL	SKPINT - SKIP FILE INTERRUPT ROUTINE

;SKPINT - ROUTINE TO HANDLE A SKIP REST OF THIS FILE INTERRUPT ON ^X
;DEBRKS TO SKPABT WITH INTERRUPT CHARACTER DISABLED IF NOT IN CRITICAL
;REGION BASED ON FL%NOX.

SKPINT:	PUSH	P,T1		;SAVE AN AC TO USE
	MOVEI	T1,SKPABT	;WHERE TO DEBRK TO
	TXNN	F,FL%NOX	;IN CRITICAL REGION?
	MOVEM	T1,@LEVTAB	;NO, CHANGE WHERE WE RETURN
	MOVX	T1,.TICCX	;CONTROL-X CODE
	TXNN	F,FL%NOX	;DO WE DISABLE IT TO AVOID MULTIPLE?
	DTI			;YES
	 ERJMP	LOSE
	POP	P,T1		;RESTORE THE AC
	DEBRK			;THEN RETURN FROM INTERRUPT
	 ERJMP	LOSE		;FAILED...
	SUBTTL	ILLEGAL MEMORY READ INTERRUPT

;IRDINT - ROUTINE TO HANDLE AN ILLEGAL MEMORY READ INTERRUPT,
;WHICH IS ASSUMED TO BE CAUSED BY A FILE WITH HOLES.
;WE TRY TO SAY WHICH FILE AND CONTINUE...

IRDINT:	MOVEM	P,PIACS+P	;SAVE THE ACS
	MOVE	P,[0,,PIACS]	; WITH A BLT
	BLT	P,PIACS+16	; TO THE SAVE BLOCK
	MOVE	P,PIACS+P	;REGET A STACK TO USE
	PUSH	P,.JBUUO##	;PUSH UUO LOC SO WE ARE INTERRUPTABLE

	MOVEI	T1,.PRIOU	;WAIT FOR A CHANCE TO
	DOBE			;GET INTO THE OUTPUT
	WARN	<File has holes -- >
	TYPJFN	FILJFN,FULL	;SAY WHICH ONE
	TYPE	<
>				;CRLF

	HRRZ	T4,PIACS+P2	;GET FAILING PAGE ADDRESS FROM EXTEND BP
	LSH	T4,-^D9		;MAKE PAGE NUMBER FOR CORE
	HRLI	T4,.FHSLF	;US
	MOVE	T1,T4		;COPY IT
	RPACS			;SEE IF THIS THE ONE
	 ERJMP	LOSE
	MOVE	T3,T2		;COPY BITS
	RMAP			;CHECK THE MAPPING
	 ERJMP	LOSE
	SKIPL	T1		;PROCESS BECOME FILE POINTER?
	TXNE	T3,PA%PEX	;PAGE EXIST?
	 ERROR	<FIND:  Internal mapping check error>
	SETOM	T1		;GUESSED RIGHT -- MAKE PAGE PRIVATE
	MOVE	T2,T4		;COPY PAGE ID AGAIN
	PMAP			;DELETE PAGE TO MAKE PRIVATE...
	 ERJMP	LOSE

	POP	P,.JBUUO##	;POP UUO LOCATION
	MOVE	P,[PIACS,,0]	;SETUP BLT AND
	BLT	P,P		; RESTORE THE ACS
	DEBRK			;THEN RETURN FROM INTERRUPT
	 ERJMP	LOSE		;FAILED...
	SUBTTL	THE DATA AREA

	XLIST			;DUMP THE LITERALS
DSLITS:	LIT
	LIST


PIACS:	BLOCK	20		;SAVED ACS DURING STATUS PSI

SAVEP:	BLOCK	1		;STORAGE OF STACK POINTER FOR COMMANDS
SAVEPX:	BLOCK	1		;STORAGE OF STACK FOR CONTROL-X

FILJFN:	BLOCK	1		;WORD USUALLY HOLDING FILE JFN
FDBBLK:	BLOCK	.FBADR+1	;SPACE FOR FDB DATA

FILSTP:	BLOCK	1		;POINTER INTO FILLST USED BY NXTFIL
FILCNT:	BLOCK	1		;COUNT OF FILES IN FILLST
FILLST:	BLOCK	MAXFIL*STRSIZ*5	;LIST OF JFNS TO SEARCH
TFSIZE:	BLOCK	1		;TOTAL SIZE OF FILE IN PAGES
FSIZE:	BLOCK	1		;SIZE OF FILE IN PAGES FOR MAPPING
BIGSEG:	BLOCK	1		;STARTING PAGE OF CURRENT SEGMENT
FBYTCT:	BLOCK	1		;BYTE COUNT FOR ENTIRE FILE

STRCNT:	BLOCK	1		;COUNT OF ENTRIES IN USE IN STRBUF
STRBUF:	BLOCK	<MAXSTR+1>*STRSIZ ;SEARCH STRINGS BUFFER

MATCHC:	BLOCK	1		;COUNT OF MATCHES SO FAR (FOR ^A)
MATCHF:	BLOCK	1		;COUNT OF FILES WITH MATCHES
FSKIP:	BLOCK	1		;NUMBER OF FILES SKIPPED OR ABORTED
LINENO:	BLOCK	1		;CURRENT LINE NUMBER
LINPTR:	BLOCK	1		;BYTE POINTER TO BEGINNING OF LAST LINE
DSTBUF:	BLOCK	1		;CROCK DESTINATION FOR MOVST
STRSV2:	BLOCK	2		;AC STORAGE FOR MORE ADJUSTMENT
SCNSVP:	BLOCK	1		;STORAGE OF P1 WHILE CALLING STRCMP
;XTBL IS THE TRANSLATION TABLE FOR THE MOVST INSTRUCTION.
;THERE ARE TWO TYPES OF ENTRIES:  FOR ALL CHARATERS TO
;BE IGNORED ON THE SCAN, THE TRANSLATION ENTRY IS THE
;CODE FOR THE CHARACTER, WITH AN OPCODE OF ZERO; AND FOR
;THOSE WE WANT TO BREAK ON, THE ENTRY IS THE CHARACTER
;CODE WITH AN OPCODE FIELD OF ONE TO TERMINATE TRANSLATION.

	DEFINE	MAKTBL,<
	XLIST
	...ZZZ==0
   REPEAT  ^D64,<
	...XXX==<...ZZZ>B17+<...ZZZ+1>
   IFE	<...ZZZ-.CHLFD>,<...XXX==<...ZZZ+100000>B17+<...ZZZ+1>>
	EXP	...XXX		;;GENERATE THE WORD
	...ZZZ==...ZZZ+2	;;BUMP THE COUNT
	>			;;END OF REPEAT
	LIST
	>			;END OF MAKTBL DEFINITION

CTBL:	MAKTBL			;BUILD THE CONSTANT TABLE TO START WITH, LF SET
XTBL:	BLOCK	^D64		;TRANSLATION TABLE FOR MOVST

	END	<3,,EVEC>