Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-12 - 43,50547/scan1.mac
There is 1 other file named scan1.mac in the archive. Click here to see a list.
UNIVERSAL	SCAN1U - Definitions for SCAN1
SUBTTL	By Joe Smith 20-Sep-77

	COMMENT	&
SCAN1 scans a file specs, converting from an ASCII string to OPEN/LOOKUP.
NACS1 does the opposite, converting OPEN/LOOKUP to an ASCII string.

  This version was written when my previous version got out-of-hand (like DEC's
version).  SCAN1 is designed to pick up one file-spec and stop at anything it
doesn't like (including "=" or "/").  This version does not care if there are
two periods, it takes the last extension as valid.  SCAN1 accepts wildcards,
but merely turns on a bit, leaving the interpretation of the question-mark or
asterisk up to the caller.  Same for the at-sign, SCAN1 decodes the indirect
file name, the caller has to read this file.  The pound-sign allows funny names
to be enterred using two octal digits per character, just like PIP.

  This code is convoluted and not very understandable, but it is small and
gets the job done.  SCAN1 is guarenteed to read:

	DEVICE:FILE.EXT<PRO>[P,PN,SFD1,...SFD5]
&  ;End COMMENT

;Global AC definitions
	T1=1			;Flag bits and last character returned here
	L=16			;Link to FORTRAN style arg list
	P=17			;PDL pointer

;Argument indices
	DEFINE PTR,<@0(L)>	;ASCII byte pointer
	DEFINE CNT,<@1(L)>	;Count of remaining chars
	DEFINE DEV,<@2(L)>	;Place to put device name
	DEFINE FIL,<@3(L)>	;4 word block for file name
		NAM==0		;File name
		EXT==1		;Extension
		PRO==2		;Protection
		PPN==3		;Directory
	DEFINE PTH,<@4(L)>	;8 word block for SFD (PATH. args)

;Scan Flags, returned in the LH of T1
	SF.SPC==1B0		;Device and/or filename found (sign bit)
	SF.DEV==1B1		;Device found
	SF.FIL==1B2		;Filename found
	SF.EXT==1B3		;Period found
	SF.PRO==1B4		;Protection found
	SF.PPN==1B5		;PPN found
	SF.SFD==1B6		;SFD's seen (PPN word points to PTH)
	SF.WLD==1B7		;Wildcards found
	SF.PP2==1B8		;PPN in front of filename
	SF.IND==1B9		;@ at-sign seen

	NOSYM			;Suppress symbol table in listing
	PRGEND			;End of UNIVERSAL SCAN1U
TITLE	SCAN1 - Small file-name scanner
SUBTTL	AC definitions

COMMENT &
	MOVEI	L,SPEC		;AC16 points to args
	PUSHJ	P,SCAN1		;Interpret the command buffer
	 *Only return*		;<flag bits,,last char> in T1
			;Preserves all other AC's, uses 12 words of stack space

	-5,,0
SPEC:	POINTR			;ASCII byte pointer to string
	ICOUNT			;Number of characters left in string
	DEVICE			;Returned as SIXBIT
	FILEXT			;Start of 4 word LOOKUP/ENTER block
	PATHB			;8 word PATH. block

&		;End of comment

	SEARCH	SCAN1U		;Get other definitions

	F=0			;Flags when in SCAN1
	T1=T1	;1		;Returned flags and last char
	T2=2			;Temp
	CH=3			;Holds char
	BP=4			;Output byte pointer
	I=5			;Index register
	L=L	;16		;Link to arg list
	P=P	;17		;PDL pointer


	TWOSEG			;Make this reentrant
	RELOC	400000		;Start in the HISEG
	XALL			;Make sure arg definitions expand nicely
SUBTTL	Entry and Exit points

ENTRY	SCAN1

	SIXBIT	/SCAN1/
SCAN1:	PUSH	P,F		;Save regs
	PUSH	P,T2
	PUSH	P,CH
	PUSH	P,BP
	PUSH	P,I
	MOVEI	I,FIL		;Point to 4-word LOOKUP block

	PUSHJ	P,SCAN2		;Go interpret the characters

	HLLZS	EXT(I)		;Only 3 letter extension
	HRRI	F," "-' '(CH)	;Convert last char back to ASCII
	SKIPE	NAM(I)		;Do we have a file name?
	 TLO	F,(SF.FIL+SF.SPC) ;Yes, flag it
	MOVE	T1,F		;Return SCAN1 flags in AC1

	POP	P,I		;Restore ACs
	POP	P,BP
	POP	P,CH
	POP	P,T2
	POP	P,F
	POPJ	P,		;Return from SCAN1
SUBTTL	Interpret command buffer

SCAN2:	SETZB	T1,DEV		;No device yet, nor PPN
	SETZB	F,NAM(I)	;No flags, no file name
	SETZM	EXT(I)		;No extension
	SETZM	PRO(I)		;No protection
	SETZM	PPN(I)		;Default directory
	MOVEI	BP,DEV		;Store the first word as the device

GETDEV:	PUSHJ	P,GETWRD	;Get a word
	CAIN	CH,':'		;Did we hit the colon?
	 JRST	GOTDEV		;Yes
	MOVSI	T1,'DSK'	;No device, assume DSK
	EXCH	T1,DEV		;Put in device name
	MOVEM	T1,NAM(I)	;Put file name in right place
	JRST	GOTNAM		;Check for extension or PPN

GOTDEV:	TLO	F,(SF.DEV+SF.SPC) ;We do have a device
	CAIN	CH,'<'		;Protection?    ;'>'
	 JRST	GETNUM		;Yes, start of number
	CAIN	CH,'['		;PPN?
	 JRST	GETPN		;Yes, get directory

;Search for file name

GETFIL:	MOVEI	BP,NAM(I)	;Point to file name
GETNXT:	PUSHJ	P,GETWRD	;Get file name or extension

;Here at the end of the current word

GOTNAM:	CAIE	CH,'<'		;Protection?    ;'>'
	CAIN	CH,'['		;Path?
	 JRST	GETNUM		;Yes, get a number
	CAIE	CH,'.'		;Period?
	 POPJ	P,		;No, illegal char, return from SCAN2
			;Note that '=', '/' and <CR> mark the end of spec

GETEXT:	TLO	F,(SF.EXT)	;We do have an extension
	MOVEI	BP,EXT(I)	;Point to the extension
	JRST	GETNXT		;Go get the extension
SUBTTL	GETNUM - Get an octal number, or PPN,SFD,SFD

GETPN:	TLNN	F,(SF.FIL+SF.EXT) ;Do we have a file name yet?
	 TLO	F,(SF.PP2)	;No, the PPN came first

GETNUM:	SETZ	T1,		;Start with zero
GETNM1:	PUSHJ	P,GETC		;Get a digit
	  JRST	GOTNUM		;No more digits
	SUBI	CH,'0'		;Convert to binary
	LSH	T1,3		;Multiply T1 by 8
	ADD	T1,CH		;Add in the number
	JRST	GETNM1		;Go for more

;'<'
GOTNUM:	CAIN	CH,'>'		;Close angle bracket?
	 JRST	GOTPRO		;Yes, protection
	CAIN	CH,']'		;End of PPN?
	 JRST	GOTPPN		;Yes
	CAIN	CH,','		;Comma?
	TLOE	F,(SF.PPN)	;Yes, first one?
	 JRST	GOTPPN		;Second comma or illegal syntax
	HRLZM	T1,PPN(I)	;Store the project number
	JRST	GETNUM		;Go for programmer number

GOTPPN:	HLL	T1,PPN(I)	;Get project number also
	GETPPN	T2,		;This will NOT skip
	TLNN	T1,-1		;Anything in the left half?
	 HLL	T1,T2		;No, insert the project number
	TRNN	T1,-1		;Anything in the right half?
	 HRR	T1,T2		;No, insert the programmer number
	MOVEM	T1,PPN(I)	;Store it
	CAIN	CH,','		;Comma after programmer?
	 JRST	GETSFD		;Yes, go for SFDs
	JRST	GETFIL		;Go for file name

GOTPRO:	LSH	T2,^D27		;Put protection into position
	MOVEM	T2,PRO(I)	;Store it
	TLO	F,(SF.PRO)	;Flag it
	JRST	GETFIL		;Look for more in file spec
SUBTTL	GETSFD and GETWRD - get SIXBIT words

GETSFD:	MOVE	T1,PPN(I)	;Get the PPN
	MOVEI	BP,PTH		;Get addr of PATH. block
	MOVEM	BP,PPN(I)	;Store for the lookup
	SETZM	0(BP)		;Clear the function word
	SETZM	1(BP)		;And the SCAN bits
	MOVEM	T1,2(BP)	;Store the PPN
	TLO	F,(SF.SFD)	;Flag SFDs seen
	ADDI	BP,3		;Point to first SFD slot

MORSFD:	CAIE	CH,','		;Another comma?
	 JRST	GOTNAM		;No, go see what it is
	HRRZS	BP		;Clear left half
	MOVEI	T1,PTH		;Get addr of PATH. block
	CAILE	BP,7(T1)	;Done 5 SFDs already?
	 MOVEI	BP,7(T1)	;Yes, 6th overwrites the 5th
	SETZM	(BP)		;Clear this SFD slot
	PUSHJ	P,GETWRD	;Get the SFD name
	CAIE	CH,']'		;Done yet?
	 AOJA	BP,MORSFD	;No, get next SFD name
	JRST	GETFIL		;Done with the path

;Routine to get a SIXBIT word and store it using BP as pointer

GETWRD:	HRLI	BP,(POINT 6,)	;Make a byte pointer
GETW1:	PUSHJ	P,GETC		;Get a letter or digit
	  JRST	GETW2		;Check for #
	TLNE	BP,770000	;Any room in this word?
	 IDPB	CH,BP		;Yes, stuff it in
	JRST	GETW1		;Go for 6

GETW2:	CAIE	CH,'#'		;Pound sign?
	 POPJ	P,		;No, return from GETWRD
GETODD:	PUSHJ	P,GETC		;Get a digit
	  POPJ	P,		;End of word
	CAILE	CH,'7'		;Octal digit?
	 POPJ	P,		;No, done
	MOVEI	T1,-'0'(CH)	;Save odd digit
	LSH	T1,3		;Shift over 3 places
	PUSHJ	P,GETC		;Get even digit
	  POPJ	P,		;Bad, but I won't complain
	CAILE	CH,'7'		;Octal only
	 POPJ	P,		;Also bad
	DPB	CH,[POINT 3,T1,35] ;Combine the two
	TLNE	BP,770000	;Any room in the word?
	 IDPB	T1,BP		;Insert the funny char
	JRST	GETODD		;Go for more
SUBTTL	Get a character from the buffer

;Get an uppercase character from the input string, ignoring blanks.

ATSIGN:	TLO	F,(SF.IND)	;Flag indirect char seen and get next char
GETC:	SETZ	CH,		;In case buffer empty
	SOSGE	CNT		;Any more chars in the buffer?
	 POPJ	P,		;No, give error return
	ILDB	CH,PTR		;Input a char
	CAIL	CH,"A"+40	;Lower case?
	CAILE	CH,"Z"+40	; ...
	 SKIPA			;No
	  SUBI	CH,40		;Yes, convert to upper
	CAIE	CH," "		;Space
	CAIN	CH,11		; or tab?
	 JRST	GETC		;Yes, ignore
	CAIE	CH,"?"		;Wild card?
	CAIN	CH,"*"		; ...
	 JRST	[TLO	F,(SF.WLD) ;Yes, flag it
		 JRST	CPOPJ1]	   ; and consider it legal
	CAIN	CH,"@"		;At sign?
	 JRST	ATSIGN		;Flag it and continue
	SUBI	CH," "-' '	;Convert to SIXBIT
	CAIL	CH,'0'		;Number
	CAILE	CH,'Z'		; or alpha?
	 POPJ	P,		;No, error return
	CAILE	CH,'9'		;Numbers and alpha only
	CAIL	CH,'A'		; ...
CPOPJ1:	AOS	(P)		;Yes, skip return
CPOPJ:	POPJ	P,		;Return from GETC


	PRGEND			;End of SCAN1
TITLE	NACS1 - Un-scanner
SUBTTL	AC definitions

COMMENT &
	MOVEI	L,SPEC		;Same argument block for NACS1
	PUSHJ	P,NACS1		;Unscan OPEN/LOOKUP back into string
	 *Only return*		;Preserves all ACs

	-5,,0
SPEC:	POINTR			;ASCII byte pointer to string
	ICOUNT			;Number of characters left in string
	DEVICE			;In SIXBIT
	FILEXT			;Start of 4 word LOOKUP/ENTER block
	PATHB			;8 word PATH. block

&		;End of comment

	SEARCH	SCAN1U		;Get other definitions

	F=0			;Flags when in SCAN1
	T1=T1	;1		;Returned flags and last char
	T2=2			;Temp
	CH=3			;Holds char
	BP=4			;Output byte pointer
	I=5			;Index register
	L=L	;16		;Link to arg list
	P=P	;17		;PDL pointer


	TWOSEG			;Make this reentrant
	RELOC	400000		;Start in the HISEG
SUBTTL	Entry and Exit points

ENTRY	NACS1

	SIXBIT	/NACS1/
NACS1:	PUSH	P,F		;Save regs
	PUSH	P,T1
	PUSH	P,T2
	PUSH	P,CH
	PUSH	P,BP
	PUSH	P,I
	MOVEI	I,FIL		;Point to 4-word LOOKUP block

	PUSHJ	P,NACS2		;Go interpret the binary data

	POP	P,I		;Restore ACs
	POP	P,BP
	POP	P,CH
	POP	P,T2
	POP	P,T1
	POP	P,F
	POPJ	P,		;Return from NACS1
SUBTTL	Unscan file specs

NACS2:	SKIPN	T2,DEV		;Get the device
	 JRST	NODEV		;Don't output anything if blank
	PUSHJ	P,OUTSIX
	MOVEI	T1,":"		;Now a colon
	PUSHJ	P,OUTASC

NODEV:	MOVE	T2,NAM(I)	;Get the file name
	PUSHJ	P,OUTSIX
	MOVEI	T1,"."		;Now a period
	PUSHJ	P,OUTASC
	HLLZ	T2,EXT(I)	;Get extension
	SKIPE	T2		;Skip it if blank
	 PUSHJ	P,OUTSIX
	SKIPN	T1,PPN(I)	;Get directory
	 JRST	OUTNUL		;Done if zero
	TLNN	T1,-1		;Anything in LH?
	 JRST	OUTSFD		;Yes, type SFDs
	PUSHJ	P,OUTPPN	;Output "[p,pn"

OUTBKT:	MOVEI	T1,"]"		;Finish off the PPN
	PUSHJ	P,OUTASC
OUTNUL:	MOVE	T2,PTR		;Get byte pointer
	MOVEI	T1,0		;Null
	IDPB	T1,T2		;Store null at end of ASCIZ string
	POPJ	P,		;All done

OUTPPN:	JUMPL	T1,OUTDEF	;Output "[-" if PPN is negative
	PUSH	P,T1		;Save programmer
	MOVEI	T1,"["
	PUSHJ	P,OUTASC
	HLRZ	T1,(P)		;Only the project
	PUSHJ	P,OUTOCT
	MOVEI	T1,","		;Now a comma
	PUSHJ	P,OUTASC
	POP	P,T1		;Get PPN back
	HRRZS	T1		;Only the programmer
				;Fall into OUTOCT and return

OUTOCT:	IDIVI	T1,10		;Get a digit
	HRLM	T2,(P)
	SKIPE	T1		;If not done,
	 PUSHJ	P,OUTOCT	;Do it again
	HLRZ	T1,(P)		;Get a digit
	ADDI	T1,"0"		;Fall into OUTASC and return
;Routine to output a single ASCII character in T1

OUTASC:	SOSL	CNT		;Decrement counter
	 IDPB	T1,PTR		;Store char
	POPJ	P,

;Routine to output a SIXBIT word in T2

OUTSIX:	SETZ	T1,		;Clear junk
	ROTC	T1,6		;Shift in a char from top of T2
	ADDI	T1,40		;Convert to ASCII
	PUSHJ	P,OUTASC
	JUMPN	T2,OUTSIX	;Loop until done
	POPJ	P,

OUTSFD:	MOVE	BP,T1		;Copy pointer to PATH
	MOVE	T1,2(BP)	;Get PPN
	PUSHJ	P,OUTPPN
	ADDI	BP,3		;Point to first SFD slot
	HRLI	BP,-5		;Make into AOBJN pointer

OUTSF1:	SKIPN	(BP)		;Check SFD
	 JRST	OUTBKT		;Done, output "]"
	MOVEI	T1,","		;Get a comma
	PUSHJ	P,OUTASC
	MOVE	T2,(BP)		;SFD name
	PUSHJ	P,OUTSIX
	AOBJN	BP,OUTSF1	;Do up to 5 of them
	JRST	OUTBKT		;Only if all 5 are non-zero

OUTDEF:	MOVEI	T1,"["		;Default directory if PPN is negative
	PUSHJ	P,OUTASC
	MOVEI	T1,"-"
	JRST	OUTASC		;Output it and return

	END			;Of NACS1