	.TITLE	FTCOMND COMMAND PARSER FOR FTCOPY
	.IDENT	/03-JAN-1982/
;	Foreign tape copy.
;	V1.a	T.W.D.	03-Jan-1982	Initail release.
;
	$TPADEF
	$SSDEF
	$CLIMSGDEF
;
	FTCBDEF			; FTCOPY CONTROL BLOCK DEFINITIONS
	FTIODEF			; FTCOPY IO BLOCK DEFINITIONS
;
;	FTCOPY input_file output_file
;
;	command qualifiers			defaults
;	/[NO]TRAN=code*				/NOTRANS
;	/[NO]BLANK_EDIT=[file_spec]		/NOBLANK_EDIT
;
;	input qualifiers
;	/FILES[=n]				/FILES=1
;	/BLOCKSIZE[=n]				/BLOCK_SIZE=input_block_size
;	/RECORD_SIZE[=n]			/RECORD_SIZE=input_block_size
;	/[NO]TRAILING_DATA[=([RECORD:[[%b]x],[BLOCK:[[%b]x])]  
;						/NOTRAILING_DATA
;
;	output qualifiers
;	/BLOCK_SIZE[=n]				/BLOCK_SIZE=input_record_size
;	/RECORD_SIZE[=n]			/RECORD_SIZE=output_block_size
;	/[NO]EVEN[=[%b]x]			/NOEVEN
;	/[NO]PAD[=([RECORD:[[%b]x],[BLOCK:[[%b]x])]
;						/NOPAD
;
;	TRANSLATION CODES - USED TO INDICATE THE TYPE OF TRANSLATION
;	TO BE DONE BETWEEN INPUT AND OUTPUT DATA BUFFERS.
;	ALLOWABLE CODES:	ASCTEBC = 0
;				EBCTASC = 1
;				8AT7A   = 2
;				7AT8A   = 4
;				USER    = 5
;
;	PADDING, EVEN, AND TRAILING CHARACTER SPECIFICATION -
;		%bx	WHERE
;			x IS ASCII A-Z, a-z, OR 0-9 (a-z MUST BE ENCLOSED IN
;				"" IN ORDER TO GET PASSED WITHOUT UPCASING).
;			x IS A NUMBER REPRESENTING AN ASCII CHARACTER AND
;			b IS THE BASE OF THE NUMBER.  VALUES FOR B MAY BE:
;				D=DECIMAL
;				O=OCTAL
;				X=HEXADECIMAL
;
;	CALLING SEQUENCE:
;		CALLS	#0,G^FT_COMND	; ALL INFORMATION PASSED THROUGH
;					  THE FT CONTROL BLOCK.
;
;	REGISTER USAGE:
;		Other than indicated below, R0-R5 may be modified by move
;		character instructions.  Care should be taken to insure their
;		integrity.
;
;		R0 - Used for checking status returned from system routines.
;		R1 - Not used.
;		R2 - Not used.
;		R3 - Not used.
;		R4 - Not used.
;		R5 - Not used.
;		R6 - Not used.
;		R7 - Used as count of bytes copied from the CLI interface
;		     routines.
;		R8 - Pointer into portions of the command string.
;		R9 - Pointer into file name strings.
;		R10 - Pointer to the FT Control Block.
;		R11 - Pointer to the FT I/O block.
;
;
	.PAGE
	.SUBTITLE TPARSE STATE TABLES AND DATA BLOCK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		CHARACTER TRANSLATION STATE TABLE.
;
	$INIT_STATE	TRANS_TABLE,TRANS_KEY
	$STATE
;
	$TRAN	'ASCTEBC',TPA$_EXIT,,TRANS_V_ASCTEBC,TEMP_CODE
	$TRAN	'EBCTASC',TPA$_EXIT,,TRANS_V_EBCTASC,TEMP_CODE
	$TRAN	'8AT7A',TPA$_EXIT,,TRANS_V_8AT7A,TEMP_CODE
	$TRAN	'7AT8A',TPA$_EXIT,,TRANS_V_7AT8A,TEMP_CODE
	$TRAN	'USER',TPA$_EXIT,,TRANS_V_USER,TEMP_CODE
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$END_STATE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		NUMBER OF FILES STATE TABLE.
;
	$INIT_STATE	N_FILE_TABLE,N_FILE_KEY
	$STATE
;
	$TRAN	TPA$_DECIMAL,TPA$_EXIT,,,TEMP_CODE
	$TRAN	'ALL',TPA$_EXIT,,32767,TEMP_CODE
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$END_STATE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;		SHORT RECORD AND BLOCK PADDING
;
	$INIT_STATE	PAD_TABLE,PAD_KEY
;
	$STATE	FIRST_PAD
	$TRAN	'RECORD',SECOND_PAD,,<<^X00000001>>,TEMP_CODE
	$TRAN	'BLOCK',SECOND_PAD,,<<^X00000002>>,TEMP_CODE
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$STATE	SECOND_PAD
	$TRAN	':',THIRD_PAD
	$TRAN	TPA$_EOS,TPA$_EXIT,DEFAULT_ACT
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$STATE	THIRD_PAD
	$TRAN	TPA$_ANY,TPA$_EXIT,PAD_CHR_ACT
	$TRAN	TPA$_EOS,TPA$_EXIT,DEFAULT_ACT
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$END_STATE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;		PARSE CHARACTERS FOR PADDING.
;
	$INIT_STATE	CHAR_TABLE,CHAR_KEY
;
	$STATE SIMPLE
	$TRAN	'%',COMPLEX
	$TRAN	TPA$_ALPHA,TPA$_EXIT,CHAR_ACT
	$TRAN	TPA$_DIGIT,TPA$_EXIT,CHAR_ACT
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$STATE	COMPLEX
	$TRAN	'D',D_NUMB
	$TRAN	'O',O_NUMB
	$TRAN	'X',X_NUMB
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$STATE	D_NUMB
	$TRAN	TPA$_DECIMAL,TPA$_EXIT,NUMB_ACT
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$STATE	O_NUMB
	$TRAN	TPA$_OCTAL,TPA$_EXIT,NUMB_ACT
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$STATE	X_NUMB
	$TRAN	TPA$_HEX,TPA$_EXIT,NUMB_ACT
	$TRAN	TPA$_LAMBDA,TPA$_FAIL
;
	$END_STATE

;
;
	.PAGE
	.SUBTITLE TPARSE ACTION SUBROUTINES.
;
;		ACTION ROUTINES FOR PARSING THE OUTPUT PAD CHARACTERS
;		FOR RECORDS OR BLOCKS.
	.ENTRY	PAD_CHR_ACT,^M<R2,R3,R4,R5,R6,R7,R8,R9>
;
;		SET UP ADDRESS OF THE BYTE LOCATION FOR THE PAD/TRAIL
;		CHARACTER.  THIS ADDRESS IS PASSED INTO THE TPARSE ACTION
;		ROUTINE THROUGH THE PARAMETER LONGWORD IN THE PARAMETER
;		BLOCK AND IS PUT INTO THE NEXT LEVEL OF PARAMETER BLOCK.
;
	MOVL	TPA$L_PARAM(AP),QUOTE_TPAR+TPA$L_PARAM
;
;		CHECK FOR BLOCK OR RECORD PADDING.  IF RECORD PADDING
;		DO NOTHING TO THE ADDRESS IN THE PARAMETER BLOCK
;
	BLBS	TEMP_CODE,30$		; CHECK FOR RECORD PAD (BIT SET)
;
;		CLEAR FOR THE "BLOCK" PAD CHARACTER.  INCREMENT THE ADDRESS
;		IN THE PARAMETER BLOCK TO GET THE BLOCK PAD BYTE.
;
	INCL	QUOTE_TPAR+TPA$L_PARAM
	BRB	30$
;
;		PARSE TO GET THE "%bx" SYNTAX.
;
;		INCREMENT THE COUNT OF CHARACTERS IN THE STRING AND MOVE INTO
;		THE NEW PARSE BLOCK.  MOVE THE TOKEN POINTER INTO THE PARSE
;		BLOCK.  THESE FORM THE STRING DESCRIPTOR FOR THE NEW PARSE.
;
30$:	ADDL3	#1,TPARSE_BLOCK+TPA$L_STRINGCNT,QUOTE_TPAR+TPA$L_STRINGCNT
	MOVL	TPARSE_BLOCK+TPA$L_TOKENPTR,QUOTE_TPAR+TPA$L_STRINGPTR
;
	PUSHAL	CHAR_KEY		; THE QUOTE PARSE KEY TABLE.
	PUSHAL	CHAR_TABLE		; THE QUOTE PARSE TABLE.
	PUSHAL	QUOTE_TPAR		; THE QUOTE PARAMATER BLOCK
	CALLS	#3,G^LIB$TPARSE
;
	RET			; REGARDLESS OF THE OUTCOME, RETURN AND
				; LET THE CALLER HANDLE ANY PROBLEMS.
;
;
;		DEFAULT CHARACTER ACTION ROUTINE.
;
	.ENTRY	DEFAULT_ACT,^M<R2,R3,R4,R5,R6,R7,R8,R9>
;
;		MOVE THE DEFAULT CHARACTER TO THE LOCATION DESIGNATED
;		BY THE FIRST BYTE OF THE TEMP_CODE (RECORD OR BLOCK PADDING).
;
	BLBS	TEMP_CODE,45$		; BRANCH IF SET FOR RECORD PAD.
;
;		INCREMENT THE ADDRESS IN THE PARAMETER BLOCK TO POINT TO
;		THE BLOCK PAD BYTE.
;
	INCL	TPA$L_PARAM(AP)
;
;		MOVE THE SPACE CHARACTER INTO THE LOCATION POINTED TO
;		BY THE PARAMETER BLOCK.
;
45$:	MOVB	SPACE_CHAR,@TPA$L_PARAM(AP)	; PUT IN DEFAULT CHAR.
	RET
;
;
;		CHARACTER ACTION ROUTINE FOR PAD CHARACTER PARSING.
;
	.ENTRY	CHAR_ACT,^M<R2,R3,R4,R5,R6,R7,R8,R9>
;
;		MOVE THE CHARACTER POINTED TO BY THE TOKEN POINTER
;		(THE CURRENT PARSE TOKEN) INTO THE STORAGE AREA.
	MOVB	@TPA$L_TOKENPTR(AP),@TPA$L_PARAM(AP)
	RET
;
;
;		NUMBER ACTION ROUTINE FOR GETTING A NUMBER OF AN ASCII
;		CHARACTER INTO A PADDING LOCATION.
;
	.ENTRY	NUMB_ACT,^M<R2,R3,R4,R5,R6,R7,R8,R9>
;
;		MOVE THE NUMBER OF THE ASCII CHARACTER INTO THE BYTE POINTED
;		TO BY THE PARAMETER IN THE PARAMETER BLOCK.
;
	MOVB	TPA$L_NUMBER(AP),@TPA$L_PARAM(AP)
	RET
;
	.PAGE
	.SUBTITLE COMMAND ANALYSIS DATA.
;
;		NAMES OF COMMAND PARAMETERS AND QUALIFIERS.
;
TRANS_NAME:	.ASCID	/TRANS_CODE/
BLNK_NAME:	.ASCID	/BLANK_EDIT/
IN_NAME:	.ASCID	/INFILE/
NUMB_NAME:	.ASCID	/NUMB_FILES/
BLOCK_NAME:	.ASCID	/BLOCK_SIZE/
RECORD_NAME:	.ASCID	/RECORD_SIZE/
OUT_NAME:	.ASCID	/OUTFILE/
EVEN_NAME:	.ASCID	/EVEN_REC/
PAD_NAME:	.ASCID	/PAD_CHARS/
TRAIL_NAME:	.ASCID	/TRAIL_DATA/
;
;		TPARSE DATA BLOCK
;
	.EVEN
TPARSE_BLOCK:	.LONG	TPA$K_COUNT0
		.LONG	TPA$M_ABBREV!TPA$M_BLANKS
		.BLKB	TPA$K_LENGTH0-8
;
QUOTE_TPAR:	.LONG	TPA$K_COUNT0
		.LONG	TPA$M_ABBREV!TPA$M_BLANKS
		.BLKB	TPA$K_LENGTH0-8
;
TEMP_CODE::	.LONG	0
SPACE_CHAR::	.BYTE	^X20
;
	.PAGE
	.SUBTITLE CODE TO ANALYZE THE COMMAND LINE.
;
	.ENTRY	FTCOMND,^M<R2,R3,R4,R5,R6,R7,R8,R9>
;
;
;		GET THE VALUES FROM ANY GENERAL (GLOBAL) COMMAND QUALIFIERS.
;		IF THERE ARE ANY MORE QUALIFIERS AT END OF ALL OF THE
;		COMMAND ANALYSIS, WE MAY HAVE TO COME BACK TO HERE AND LOOK
;		FOR THE GLOBAL QUALIFIERS AGAIN.
;
;		GET ANY TRANSLATION CODES - 8 CHARACTERS MAX.
	GETVAL	8,TRANS_NAME,10$
;
;		RETURN = FALSE, GO GET BLANK EDIT INFORMATION.
;
	JMP	GET_BLANK
;
;			BUILD THE STRING DESCRIPTOR FOR PARSING THE
;			INPUT TRANSLATION CODE AND THEN CALL THE PARSER
;			TO FIGURE OUT WHICH CODE WE ARE WORKING WITH.
;
10$:	CLRL	TEMP_CODE		; CLEAR TEMPORARY STORAGE.
	MOVL	R7,TPARSE_BLOCK+TPA$L_STRINGCNT		; PUT CHAR. COUNT
	MOVL	FTCB_L_INSPTR(R10),TPARSE_BLOCK+TPA$L_STRINGPTR
;
	PUSHAL	TRANS_KEY
	PUSHAL	TRANS_TABLE
	PUSHAL	TPARSE_BLOCK
	CALLS	#3,G^LIB$TPARSE		; PARSE THE TRANSLATION CODE.
;
	BLBS	R0,20$
;			TRANSLATION CODE SYNTAX ERROR.
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_TRACODSYN,#2,-
		R7,FTCB_L_INSPTR(R10)
;
20$:	MOVB	TEMP_CODE,FTCB_B_TCODE(R10)	; SAVE TRANS CODE.
	BBCS	#FLAG_V_TRANS,FTCB_W_FLAG(R10),GET_BLANK  ; CLEAR BIT 
				; INDICATING NOT USING THE DEFAULT.
;
;
;		LOOK FOR THE BLANK_EDIT QUALIFIER.
;
GET_BLANK:
;		GET THE BLANK EDIT FILE/LOGICAL NAME - 128 BYTES MAX.
	GETVAL	128,BLNK_NAME,10$
;
;		RETURN = FALSE, GO GET THE INPUT FILE NAME AND QUALIFIERS.
	BRB	GET_INFILE
;
10$:	BBCC	#DEFS_V_BLEDT,FTCB_W_DEFS(R10),11$	; DON'T USE DEFAULT.
11$:	BBCS	#FLAG_V_BLANK,FTCB_W_FLAG(R10),12$	; DO BLANK EDIT.
;
12$:	MOVL	FTCB_L_INSPTR(R10),R8	; GET THE FROM POINTER.
	MOVL	FTIO_L_BLAPTR(R11),R9	; GET THE "TO" POINTER.
;
	MOVC3	R7,(R8),(R9) 		; MOVE THE FILE NAME TO
	MOVL	R7,FTIO_L_BLASIZ(R11)	; PERM. STORAGE AND SAVE THE LENGTH.
	.PAGE
	.SUBTITLE GET THE INPUT FILE NAME AND ITS QUALIFIERS.
;
GET_INFILE:
;		GET THE INPUT FILE NAME - 128 MAX.
	GETVAL	128,IN_NAME,10$
;
;		RETURN = FALSE, PARSER DIDN'T WORK SO WE WON'T EITHER.
	CALL_MSG	EXIT_SYS,#FTC_SYSERROR,#0,#FTC_NOFIL,#2,-
		MSG_1,MSG_1+4
;
;		GOOD FILE NAME FETCH - STORE OR FUTURE REF.
10$:	MOVL	FTCB_L_INSPTR(R10),R8		; GET THE "FROM" POINTER
	MOVL	FTIO_L_INPTR(R11),R9		; GET THE "TO" POINTER
;
	MOVC3	R7,(R8),(R9) 		; SAVE FILE NAME AND
	MOVL	R7,FTIO_L_INSIZ(R11)		; THE LENGTH.
;
GET_NUMB_FILE:
;		GET THE NUMBER OF FILES TO COPY.
	GETVAL	6,NUMB_NAME,10$
;
;		RETURN = FALSE, WE HAD BETTER HAVE THE DEFAULT VALUE.
	BRW	GET_BLOCK
;
;		RETURNED A VALUE - USE THE PARSER TO DETERMINE WHAT IT IS
;		AND SAVE IT FOR ME.
;		BUILD THE DESCRIPTOR FOR THE N_FILE STRING AND CALL TPARSE.
;
10$:	CLRL	TEMP_CODE		; CLEAR THE TEMPORARY STORAGE.
	MOVL	R7,TPARSE_BLOCK+TPA$L_STRINGCNT
	MOVL	FTCB_L_INSPTR(R10),TPARSE_BLOCK+TPA$L_STRINGPTR
;
	PUSHAL	N_FILE_KEY
	PUSHAL	N_FILE_TABLE
	PUSHAL	TPARSE_BLOCK
	CALLS	#3,G^LIB$TPARSE
;
	BLBS	R0,30$
;			SYNTAX ERROR OR SOMETHING.
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_NUMFILSYN,-
		#2,R7,FTCB_L_INSPTR
;
;		COPY NFILES AND CHECK TO BE SURE IT IS NOT NEGATIVE.
30$:	MOVL	TEMP_CODE,FTCB_L_NFILES(R10)	; SAVE THE NUMBER OF FILES.
	BGTR	GET_BLOCK		; IF IT WAS > 0, BRANCH TO CONTINUE.
; 			EXIT - NO NEGATIVES ALLOWED.
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_NEGNOTPER,-
		#2,MSG_3,MSG_3+4
;
;
GET_BLOCK:
;		GET THE INPUT BLOCK LENGTH - MAX. 6 CHAR.
	GETVAL	6,BLOCK_NAME,10$
;
;		RETURN = FALSE, GET NEXT QUALIFIER.
	BRW	GET_RECORD
;
;		RETURN = TRUE, TRANSLATE THE CHARACTER STRING INTO
;		A LONGWORD.
10$:	BBCC	#DEFS_V_INBLK,FTCB_W_DEFS(R10),11$  ; CLEAR DEFAULT FLAG
11$:	PUSHAL	FTCB+FTCB_L_INBLK
	PUSHL 	FTCB_L_INSPTR(R10)
	PUSHL	R7
	CALLS	#3,G^LIB$CVT_DTB
;
	BLBS	R0,20$
;			BAD CONVERSION, BOMB OUT.
	CALL_MSG	EXIT_SYS,#FTC_NUMCONERR,#4,MSG_1,MSG_1+4,-
		MSG_4,MSG_4+4,#FTC_CHASTR,#2,R7,FTCB_L_INSPTR(R10)
;
;		CHECK THE SIZE OF THE BLOCK SIZE.
;
20$:	CMPL	FTCB_L_INBLK(R10),#^X0000000E	; CHECK TO BE SURE THAT THE
	BGEQ	30$			; IN BLOCK SIZE IS >= 14 BYTES.
;
; 		ABORT - TOO SMALL A BLOCK SIZE.
	CALL_MSG	EXIT_SYS,#FTC_BLKSIZ,#4,MSG_1,MSG_1+4,MSG_6,MSG_6+4,-
		#FTC_MINSIZE,#1,FTCB_L_INBLK(R10)
;
30$:	CMPL	FTCB_L_INBLK(R10),#^X0000FFFF	; CHECK TO BE SURE THAT THE
	BLEQ	40$			; IN BLOCK SIZE IS <= 65535. BYTES
;
; 		ABORT - TOO LARGE AN INPUT BLOCK SIZE.
	CALL_MSG	EXIT_SYS,#FTC_BLKSIZ,#4,MSG_1,MSG_1+4,MSG_7,-
		MSG_7+4,#FTC_MAXSIZE,#2,NUM_1,FTCB_L_INBLK(R10)
;
;		CHECK TO BE SURE BLOCK SIZE IS NOT NEGATIVE.
40$:	TSTL	FTCB_L_INBLK(R10)
	BGTR	GET_RECORD
; 		EXIT - NO NEGATIVES ALLOWED.
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_NEGNOTPER,#2,-
		MSG_4,MSG_4+4
;
;
GET_RECORD:
;		GET THE INPUT RECORD LENGTH - MAX. 6 CHAR.
	GETVAL	6,RECORD_NAME,10$
;
;		RETURN = FALSE
	BRW	GET_TRAIL
;
;		RETURN = TRUE, TRANSLATE THE CHARACTER STRING INTO
;		A LONGWORD.
10$:	BBCC	#DEFS_V_INREC,FTCB_W_DEFS(R10),11$  ; CLEAR DEFAULT FLAG.
11$:	PUSHAL	FTCB+FTCB_L_INREC
	PUSHL	FTCB_L_INSPTR(R10)
	PUSHL	R7
	CALLS	#3,G^LIB$CVT_DTB
;
	BLBS	R0,20$
;			BAD CONVERSION, BOMB OUT.
	CALL_MSG	EXIT_SYS,#FTC_NUMCONERR,#4,MSG_1,MSG_1+4,MSG_5,-
		MSG_5+4,#FTC_CHASTR,#2,R7,FTCB_L_INSPTR(R10)
;
;		CHECK SIZE OF INPUT RECORD.
;
20$:	CMPL	FTCB_L_INREC(R10),#^X0000FFFF	; CHECK TO BE SURE THAT THE
	BLEQ	30$			; INPUT RECORD IS <= 65535 BYTES.
;
; 		ABORT - TOO LARGE AN INPUT RECORD.
	CALL_MSG	EXIT_SYS,#FTC_RECSIZ,#2,MSG_1,MSG_1+4,-
		#FTC_MAXSIZE,#2,NUM_1,FTCB_L_INREC(R10)
;
;		CHECK TO BE SURE RECORD SIZE IS NOT NEGATIVE.
30$:	TSTL	FTCB_L_INREC(R10)
	BGTR	40$
; 		EXIT - NO NEGATIVES ALLOWED.
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_NEGNOTPER,#2,-
		MSG_5,MSG_5+4
;
;		CHECK THE INPUT RECORD AND BLOCK SIZES TO BE SURE THAT
;		THE RECORDS THE USER SPECIFIED WERE SMALLER THAN THE BLOCKS.
;
40$:	BBS	#DEFS_V_INBLK,FTCB_W_DEFS(R10),GET_TRAIL
;
;		BOTH THE RECORD AND BLOCK WERE SPECIFIED, COMPARE THE SIZES.
	CMPL	FTCB_L_INREC(R10),FTCB_L_INBLK(R10)
	BLEQ	GET_TRAIL		; RECORD IS <= BLOCK
;
; 		FATAL - RECORD > BLOCK
	CALL_MSG	EXIT_SYS,#FTC_RECGTRBLK,#2,MSG_1,MSG_1+4
;
;
;		GET THE TRAILING QUALIFIER.
;
GET_TRAIL:
	GETVAL	11,TRAIL_NAME,10$
;
;		RETURN = FALSE, GO LOOK FOR THE NEXT QUALIFIER.
	BRW	GET_OUTFILE
;
;		RETURN = TRUE, KEEP TRAILING SPECIFIED - 
;		PARSE THE REMAINDER OF THE QUALIFIER.
;		
10$:	PUSHAW	FTCB+FTCB_W_TRAILS	; LOCATION OF DESIRED BYTE.
	CALLS	#1,G^FT_CTPAR		; SET UP FOR TPARSE CALL.
;
	PUSHAL	PAD_KEY
	PUSHAL	PAD_TABLE
	PUSHAL	TPARSE_BLOCK
	CALLS	#3,G^LIB$TPARSE
;
	BLBS	R0,15$
;
; 		BAD PARSE - EXIT WITH STATUS
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_TRAILSYN,#2,-
		R7,FTCB_L_INSPTR(R10)
;
;		PARSE OK - CALL ROUTINE TO SET TYPE BIT.
;
15$:	PUSHL	#FLAG_M_TRAILB	; TRAIL BLOCK
	PUSHL	#FLAG_M_TRAILR	; TRAIL REC.
	CALLS	#2,FT_PMASK
;
;
;		CHECK FOR MORE TRAIL DEFINITIONS.
;
25$:	GETVAL	11,TRAIL_NAME,30$
;
;		RETURN = FALSE, END OF PAD CHARACTER DEFINITION.
	BRB	GET_OUTFILE
;
;		RETURN = TRUE, PAD CHARACTER SPECIFIED - PARSE CHARACTER.
30$:	PUSHAW	FTCB+FTCB_W_TRAILS	; DESTINATION OF DESIRED BYTE.
	CALLS	#1,G^FT_CTPAR		; CALL PARSE SETUP.
;
	PUSHAL	PAD_KEY
	PUSHAL	PAD_TABLE
	PUSHAL	TPARSE_BLOCK
	CALLS	#3,G^LIB$TPARSE
;
	BLBS	R0,35$
;
; 		BAD PARSE - EXIT WITH STATUS
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_TRAILSYN,#2,-
		R7,FTCB_L_INSPTR(R10)
;
;		PARSE OK - CALL ROUTINE TO SET TYPE BIT.
;
35$:	PUSHL	#FLAG_M_TRAILB	; TRAIL BLOCK
	PUSHL	#FLAG_M_TRAILR	; TRAIL REC.
	CALLS	#2,FT_PMASK
;
	.PAGE
	.SUBTITLE GET THE OUTPUT FILE NAME AND ITS QUALIFIERS.
;
GET_OUTFILE:
;		GET THE OUTPUT FILE NAME - 128 MAX.
	GETVAL	128,OUT_NAME,10$
;
;		RETURN = FALSE, PARSER DIDN'T WORK SO WE WON'T EITHER.
	CALL_MSG	EXIT_SYS,#FTC_SYSERROR,#0,#FTC_NOFIL,#2,-
		MSG_2,MSG_2+4
;
;		GOOD FILE NAME FETCH - STORE FOR FUTURE REF.
10$:	MOVL	FTCB_L_INSPTR(R10),R8		; GET THE "FROM" POINTER
	MOVL	FTIO_L_OUTPTR(R11),R9		; GET THE "TO" POINTER
;
	MOVC3	R7,(R8),(R9) 		; SAVE FILE NAME AND
	MOVL	R7,FTIO_L_OUTSIZ(R11)		; THE LENGTH.
;
;		GET THE QUALIFIER FOR EVENING AN OUTPUT BLOCK.
;
GET_EVEN:		; CHECK FOR PRESENT WITH TRUE, DEFAULTED, AND
	GETPRES	EVEN_NAME,10$,,,10$	; LOCALLY PRESENT SPECIFIED.
;
;		RETURN = FALSE, GO TO GET THE NEXT QUALIFIER.
	BRW	GET_OUT_BLOCK
;
;		RETURN = TRUE, GET THE VALUE SPECIFIED AND PARSE OUT THE
;		CHARACTER TO USE.
10$:	BBCS	#FLAG_V_EVEN,FTCB_W_FLAG(R10),11$	; CLEAR DEFAULT FLAG.
11$:	GETVAL	5,EVEN_NAME,20$
;
;		RETURN = FALSE, JUMP TO GET THE NEXT QUALIFIER.
	MOVB	SPACE_CHAR,FTCB_B_EVEN(R10)	; PUT IN THE DEFAULT CHARACTER.
	JMP	GET_OUT_BLOCK
;
;		RETURN = TRUE, PARSE OUT THE CHARACTER FROM THE INPUT STRING.
20$:	CLRL	TEMP_CODE	; CLEAR THE TEMP CODE.
;
;		BUILD THE STRING POINTER FOR TPARSE AND SET THE ADDRESS
;		OF THE DESTINATION FOR THE BYTE.
;
	MOVL	R7,QUOTE_TPAR+TPA$L_STRINGCNT
	MOVL	FTCB_L_INSPTR(R10),QUOTE_TPAR+TPA$L_STRINGPTR
;
	MOVAL	FTCB+FTCB_B_EVEN,QUOTE_TPAR+TPA$L_PARAM
;
	PUSHAL	CHAR_KEY		; QUOTE KEY TABLE
	PUSHAL	CHAR_TABLE		; QUOTE PARSE TABLE
	PUSHAL	QUOTE_TPAR		; QUOTE PARAMETER BLOCK
	CALLS	#3,G^LIB$TPARSE
;
	BLBS	R0,GET_OUT_BLOCK
;
; 		ABORT - PARSE FAILURE.
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_EVENSYN,#2,-
		R7,FTCB_L_INSPTR(R10)
;
;
;		GET THE OUTPUT BLOCK SIZE.
;
GET_OUT_BLOCK:
	GETVAL	6,BLOCK_NAME,10$
;
;		RETURN = FALSE, GET NEXT QUALIFIER.
	BRW	GET_OUT_REC
;
;		RETURN = TRUE, CONVERT CHARS. TO LONGWORD.
10$:	BBCC	#DEFS_V_OUTBLK,FTCB_W_DEFS(R10),11$	; CLEAR DEFAULT FLAG.
11$:	PUSHAL	FTCB+FTCB_L_OUTBLK
	PUSHL	FTCB_L_INSPTR(R10)
	PUSHL	R7
	CALLS	#3,G^LIB$CVT_DTB
;
	BLBS	R0,20$
;
; 		ABORT - BAD NUMBER CONVERSION.
	CALL_MSG	EXIT_SYS,#FTC_NUMCONERR,#4,MSG_2,MSG_2+4,-
		MSG_4,MSG_4+4,#FTC_CHASTR,#2,R7,FTCB_L_INSPTR(R10)
;
;		CHECK SIZE OF OUTPUT BLOCK.
;
20$:	CMPL	FTCB_L_OUTBLK(R10),#^X0000000E	; CHECK TO BE SURE THAT THE
	BGEQ	30$			; OUTPUT BLOCK SIZE IS >= 14 BYTES.
;
; 		ABORT - TOO SMALL AN OUTPUT BLOCK.
	CALL_MSG	EXIT_SYS,#FTC_BLKSIZ,#4,MSG_2,MSG_2+4,MSG_6,-
		MSG_6+4,#FTC_MINSIZE,#1,FTCB_L_OUTBLK(R10)
;
30$:	CMPL	FTCB_L_OUTBLK(R10),#^X0000FFFF	; CHECK TO BE SURE THAT THE
	BLEQ	40$			; OUTPUT BLOCK SIZE IS <= 65535 BYTES.
;
; 		ABORT - TOO LARGE AN OUTPUT BLOCK.
	CALL_MSG	EXIT_SYS,#FTC_BLKSIZ,#4,MSG_2,MSG_2+4,MSG_7,MSG_7+4,-
		#FTC_MAXSIZE,#2,NUM_1,FTCB_L_OUTBLK(R10)
;
;		CHECK TO BE SURE RECORD SIZE IS NOT NEGATIVE.
40$:	TSTL	FTCB_L_OUTBLK(R10)
	BGTR	GET_OUT_REC
; 		EXIT - NO NEGATIVES ALLOWED.
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_NEGNOTPER,-
		#2,MSG_4,MSG_4+4
;
;
;		GET THE OUTPUT RECORD SIZE.
;
GET_OUT_REC:
	GETVAL	6,RECORD_NAME,10$
;
;		RETURN = FALSE, GET NEXT QUALIFIER.
	BRW	GET_PAD
;
;		RETURN = TRUE, CONVERT CHAR. STRING TO LONGWORD.
10$:	BBCC	#DEFS_V_OUTREC,FTCB_W_DEFS(R10),11$	; CLEAR DEFAULT FLAG
11$:	PUSHAL	FTCB+FTCB_L_OUTREC
	PUSHL	FTCB_L_INSPTR(R10)
	PUSHL	R7
	CALLS	#3,G^LIB$CVT_DTB
;
	BLBS	R0,20$
;
; 		ABORT - BAD NUMBER CONVERSION.
	CALL_MSG	EXIT_SYS,#FTC_NUMCONERR,#4,MSG_2,MSG_2+4,-
		MSG_5,MSG_5+4,#FTC_CHASTR,R7,FTCB_L_INSPTR(R10)
;
;		CHECK SIZE OF OUTPUT RECORD.
;
20$:	CMPL	FTCB_L_OUTREC(R10),#^X0000FFFF	; CHECK TO BE SURE THAT THE
	BLEQ	30$			; OUTPUT RECORD SIZE IS <= 65535 BYTES.
;
; 		ABORT - TOO LARGE AN OUTPUT RECORD.
	CALL_MSG	EXIT_SYS,#FTC_RECSIZ,#2,MSG_2,MSG_2+4,-
		#FTC_MAXSIZE,#2,NUM_1,FTCB_L_OUTREC(R10)
;
;		CHECK TO BE SURE RECORD SIZE IS NOT NEGATIVE.
30$:	TSTL	FTCB_L_OUTREC(R10)
	BGTR	40$
; 		EXIT - NO NEGATIVES ALLOWED.
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_NEGNOTPER,#2,-
		MSG_5,MSG_5+4
;
;		CHECK THE RECORD AND BLOCK SIZES TO BE SURE THAT THE
;		RECORD IS <= BLOCK IF SPECIFIED.
;
40$:	BBS	#DEFS_V_OUTBLK,FTCB_W_DEFS(R10),GET_PAD
;
;		BOTH THE BLOCK AND RECORD SIZE SPECIFIED - CHECK SIZES.
;
	CMPL	FTCB_L_OUTREC(R10),FTCB_L_OUTBLK(R10)
	BLEQ	GET_PAD			; RECORD <= BLOCK - - OK.
;
; 		FATAL - RECORD > BLOCK.
	CALL_MSG	EXIT_SYS,#FTC_RECGTRBLK,#2,MSG_2,MSG_2+4
;
;
;		GET THE CHARACTER(S) TO USE IN PADDING THE OUTPUT
;
GET_PAD:
	GETVAL	11,PAD_NAME,10$
;
;		RETURN = FALSE, GO LOOK FOR THE NEXT QUALIFIER.
	BRW	45$
;
;		RETURN = TRUE, PAD CHARACTER SPECIFIED - SET FLAG TO INDICATE
;		THAT WE WILL PAD SOMETHING AND PARSE THE REMAINDER OF
;		THE QUALIFIER.
10$:	BBCC	#DEFS_V_PDEF,FTCB_W_DEFS(R10),11$	; CLEAR PAD DEFAULT FLG
;
11$:	PUSHAW	FTCB+FTCB_W_PADS	; LOCATION OF DESIRED BYTE.
	CALLS	#1,G^FT_CTPAR		; SET UP FOR TPARSE CALL.
;
	PUSHAL	PAD_KEY
	PUSHAL	PAD_TABLE
	PUSHAL	TPARSE_BLOCK
	CALLS	#3,G^LIB$TPARSE
;
	BLBS	R0,15$
;
; 		BAD PARSE - EXIT WITH STATUS
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_PADSYN,-
		#2,R7,FTCB_L_INSPTR(R10)
;
;		PARSE OK - CALL ROUTINE TO SET TYPE BIT.
;
15$:	PUSHL	#FLAG_M_PBLK	; PAD BLOCK
	PUSHL	#FLAG_M_PREC	; PAD REC.
	CALLS	#2,FT_PMASK
;
;
;		CHECK FOR MORE PAD DEFINITIONS.
;
25$:	GETVAL	11,PAD_NAME,30$
;
;		RETURN = FALSE, END OF PAD CHARACTER DEFINITION.
	BRB	45$
;
;		RETURN = TRUE, PAD CHARACTER SPECIFIED - PARSE CHARACTER.
30$:	PUSHAW	FTCB+FTCB_W_PADS	; DESTINATION OF DESIRED BYTE.
	CALLS	#1,G^FT_CTPAR		; CALL PARSE SETUP.
;
	PUSHAL	PAD_KEY
	PUSHAL	PAD_TABLE
	PUSHAL	TPARSE_BLOCK
	CALLS	#3,G^LIB$TPARSE
;
	BLBS	R0,35$
;
; 		BAD PARSE - EXIT WITH STATUS
	CALL_MSG	EXIT_SYS,#FTC_COMLINERR,#0,#FTC_PADSYN,-
		#2,R7,FTCB_L_INSPTR(R10)
;
;		PARSE OK - CALL ROUTINE TO SET TYPE BIT.
;
35$:	PUSHL	#FLAG_M_PBLK	; PAD BLOCK
	PUSHL	#FLAG_M_PREC	; PAD REC.
	CALLS	#2,FT_PMASK
;
;		PARSE OK - CHARACTER AND TYPE SHOULD BE DEFINED.
45$:
RETURN:	MOVZWL	#SS$_NORMAL,R0
	RET			; RETURN FROM THE SUBROUTINE.
;
	.PAGE
	.SUBTITLE SUBROUTINE TO SET PAD TYPE BITS IN THE FLAG WORD.
;
;		ROUTINE USES MASKS PUSHED ONTO THE STACK TO SET THE
;		BITS IN THE FT CONTROL BLOCK.
;
	.ENTRY	FT_PMASK,^M<>	; DON'T SAVE MASKS.
;
;		CHECK ON THE PAD TYPE AND SET BIT.
;
	BLBS	TEMP_CODE,40$		; BRANCH IF RECORD.
;
	BISW2	8(AP),FTCB_W_FLAG(R10)	; SET PAD BLOCK
	RET
;
40$:	BISW2	4(AP),FTCB_W_FLAG(R10)	; SET PAD RECORD.
	RET
;
	.PAGE
	.SUBTITLE SUBROUTINE TO SET UP FOR A CALL TPARSE
;
;		SUBROUTINE TO SET UP FOR A CALL TO LIB$TPARSE TO
;		PARSE OUT A PADDING CHARACTER.
;
	.ENTRY	FT_CTPAR,^M<>	; DON'T SAVE REGS.
;
	CLRL	TEMP_CODE	; CLEAR THE TEMP CODE.
;
;		BUILD THE STRING POINTER FOR TPARSE AND SET THE ADDRESS
;		OF THE DESTINATION FOR THE BYTE.
;
	MOVL	R7,TPARSE_BLOCK+TPA$L_STRINGCNT
	MOVL	FTCB_L_INSPTR(R10),TPARSE_BLOCK+TPA$L_STRINGPTR
;
	MOVL	4(AP),TPARSE_BLOCK+TPA$L_PARAM
;
	RET
	.END
