.TITLE CC000 .IDENT /X01/ .NLIST BEX .ENABL LC ; ; C COMPILER ; PARSE COMMAND LINE ; ; VERSION X01 ; ; DAVID G. CONROY 13-JAN-78 ; .GLOBL CC000 .GLOBL CSI .GLOBL DFNB1 .GLOBL DFNB2 .MCALL CALL .MCALL CALLR .MCALL RETURN .MCALL FDAT$R .MCALL FDOP$R .MCALL FINIT$ .MCALL CSI$ .MCALL CSI$1 .MCALL CSI$2 .MCALL OPEN$A .MCALL OPEN$W .MCALL OPEN$R .MCALL OFNB$W .MCALL CLOSE$ .MCALL NMBLK$ .MCALL DIR$ .MCALL WTSE$S .MCALL GMCR$ .MCALL QIO$ CSI$ ; ; EQUIVALENCES ; BLANK = 40 ;ASCII BLANK CR = 15 ;ASCII CARRIAGE RETURN ALT = 33 ;ASCII ALTMODE DOL = 44 ;ASCII DOLLAR SIGN ; ; LOCAL DATA ; SFILE: .WORD 0 ;PTR TO SOURCE FILE APPEND: .WORD 0 ;FLAG FOR '>>' EFILE: .WORD TI ;PTR TO ERROR FILE IOS: .BLKW 2 ;IO STATUS BLOCK SRC: .RAD50 /SRC/ ;FILETYPES INT: .RAD50 /INT/ ; ASM: .RAD50 /S / ; CSI: .BLKB C.SIZE ;CSI WORK BLOCK DFNB1: NMBLK$ ,,,SY ;DEFAULT FILENAME BLOCKS DFNB2: NMBLK$ ,C,,SY ; GMCR: GMCR$ ;GET MCR COMMAND LINE BLOCK GMCRP: QIO$ IO.WVB,1,1,,,, ;PROMPT QIO DPB GMCRR: QIO$ IO.RVB,1,1,,IOS,, ;READ LINE ; ; ASCII DATA. ; TI: .ASCIZ 'TI:' PRM: .ASCIZ 'CCX>' MSG01: .ASCIZ 'Usage: ccx [-ipstv] file' MSG02: .ASCIZ 'Cannot open error file' MSG03: .ASCIZ 'Cannot open input file' MSG04: .ASCIZ 'Cannot open intermediate file' MSG05: .ASCIZ 'Cannot open output file' MSG06: .ASCIZ '?: Ignored' .EVEN ;+ ; ** CC000 - PARSE COMMAND LINE ; ; THIS ROUTINE IS CALLED BY THE ROOT. IT READS THE MCR COMMAND LINE ; (PERHAPS GETTING IT FROM THE USER TI:, IF THE GMCR$ FAILS). THEN ; IT PARSES IT INTO ARGUMENTS, SETTING THE OPTION FLAGS. ; ; THE ERROR STREAM IS OPENED ON THE EFDB. A TEMP FILE IS OPENED FOR ; WRITING ON THE SFDB, THE USER'S SOURCE IS OPENED ON THE AFDB, AND ; THE PREPROCESSOR (CCPREP) IS CALLED. ; ; THE USER'S SOURCE FILE IS THEN CLOSED. THE IFDB AND AFDB, USED IN ; PREPROCESSING, ARE OPENED UP AS THE INTERMEDIATE CODE AND OUTPUT ; FILES. CONTROL RETURNS TO THE ROOT. ;- CC000: FINIT$ ;INITIALISE THE FSR DIR$ #GMCR ;GET MCR LINE BCC 20$ ;OK 10$: DIR$ #GMCRP ;PROMPT FOR THE LINE WTSE$S #1 ; DIR$ #GMCRR ;READ IT BACK WTSE$S #1 ; CMP IOS,#IS.CR ;WAS THE LINE GOOD BNE 10$ ;NO MOV IOS+2,R0 ;PUT CR ON THE END MOVB #CR,GMCR+G.MCRB(R0) ;FOR THE SCAN 20$: MOV #GMCR+G.MCRB,R0 ;POINT TO THE LINE 30$: MOVB (R0)+,R1 ;SKIP OVER COMMAND NAME CMPB R1,#CR ; BEQ 130$ ;DONE CMPB R1,#ALT ; BEQ 130$ ;DONE CMPB R1,#BLANK ; BNE 30$ ;KEEP LOOKING 40$: MOVB (R0)+,R1 ;SKIP CMPB R1,#BLANK ;BLANKS BETWEEN BEQ 40$ ;ARGS CMPB R1,#CR ; BEQ 130$ ;DONE CMPB R1,#ALT ; BEQ 130$ ;DONE CMPB R1,#'- ;OPTIONS BNE 60$ ;NO 50$: MOVB (R0)+,R1 ;OPTION CHARACTER CMPB R1,#CR ; BEQ 130$ ;DONE CMPB R1,#ALT ; BEQ 130$ ;DONE CMPB R1,#BLANK ; BEQ 40$ ;GO GET THE NEXT ARG. CALL OPT ;PROCESS OPTIONS BR 50$ ; 60$: CLR R2 ;CLEAR QUOTES FLAG CMPB R1,#'" ;CHECK FOR QUOTES BEQ 70$ ; CMPB R1,#'' ; BNE 80$ ;BR IF NOT A QUOTE 70$: MOV R1,R2 ;SAVE QUOTE DELIMITER TST SFILE ;DO WE HAVE A FILE BNE 140$ ;YES, ERROR MOV R0,SFILE ;SAVE THE FILE POINTER BR 90$ ;GO COLLECT NAME 80$: CMPB R1,#'< ;INPUT REDIRECTION BEQ 90$ ;IS DISCARDED CMPB R1,#'> ;OUTPUT REDIRECTION BNE 85$ ;NO CMPB R1,(R0) ;IS THIS '>>' BNE 82$ ;NO INC APPEND ;SET APPENDING INC R0 ;SKIP OVER THE SECOND '>' 82$: MOV R0,EFILE ;SAVE ERROR FILE NAME BR 90$ ;GO GET NAME 85$: TST SFILE ;DO WE HAVE A FILE BNE 140$ ;YES, ERROR MOV R0,SFILE ;SET POINTER DEC SFILE ; 90$: MOVB (R0)+,R1 ;COLLECT THE ARG. CMPB R1,#CR ; BEQ 110$ ;DONE CMPB R1,#ALT ; BEQ 110$ ;DONE TST R2 ;QUOTED ARGUMENT BNE 100$ ;BR IF YES CMPB R1,#BLANK ;STOP ON BLANKS BEQ 110$ ;DONE BR 90$ ;KEEP GOING 100$: CMP R1,R2 ;STOP ON MATCHING QUOTE BNE 90$ ;KEEP GOING 110$: CLRB -1(R0) ;MAKE ARG ASCIZ CMPB R1,#CR ;CHECK FOR END OF LINE BEQ 120$ ;DONE CMPB R1,#ALT ; BNE 40$ ;GO GET NEXT ARG 120$: TST R2 ;CHECK FOR MISMATCHED QUOTES BNE 140$ ;ERROR 130$: TST SFILE ;DID WE GET A FILE BNE 200$ ;BR IF YES 140$: MOV #MSG01,R0 ;COMMAND LINE BOTCH JMP 300$ ;ERROR EXIT ; ; OPEN ERROR STREAM. ; 200$: MOV EFILE,R0 ;FILE NAME CALL DSPT ;BUILD THE DSPT BCS 220$ ;URK MOV #EFDB,R0 ;GET PTR TO THE FDB FDAT$R ,#R.VAR,#FD.CR ;SET RECORD ATTRIBUTES FDOP$R ,,#CSI+C.DSDS ;DATASET DESCRIPTOR FDOP$R ,,,#DFNB1 ;DEFAULT FILENAME BLOCK TST APPEND ;APPENDING BEQ 210$ ;NO OPEN$A ;TRY OPEN FOR APPEND BCC 230$ ;WORKED CMPB F.ERR(R0),#IE.NSF ;IS THE ERROR NO FILE BNE 220$ ;NO, HARD ERROR 210$: OPEN$W ;TRY OPEN FOR WRITE BCC 230$ ;OK 220$: MOV #MSG02,R0 ;CANNOT CREATE ERROR FILE BR 300$ ; ; ; PREPROCESSING. ; 230$: MOV SFILE,R0 ;GET SOURCE FILE NAME CALL DSPT ; BCS 240$ ;URK MOV #AFDB,R0 ;OPEN FILE FDOP$R ,,#CSI+C.DSDS ;DATASET DESCRIPTOR FDOP$R ,,,#DFNB2 ;DEFAULT FILENAME BLOCK (.C) OPEN$R ; BCC 250$ ;OK 240$: MOV #MSG03,R0 ;CANNOT OPEN INPUT FILE BR 300$ ; 250$: CLR SFDB+F.FNB ;CLEAR OLD FILE ID MOV #AFDB+F.FNB+N.FNAM,R0 ;POINT AT FILE NAME IN FNB MOV #SFDB+F.FNB+N.FNAM,R1 ;POINT AT FILE NAME IN FNB 260$: MOV (R0)+,(R1)+ ;COPY FNB CMP R0,#AFDB+F.FNB+S.FNB ; BLO 260$ ; MOV SRC,SFDB+F.FNB+N.FTYP ;BUT MAKE IT .SRC MOV #SFDB,R0 ;SET UP ATTRIBUTES FDAT$R ,#R.VAR,#FD.CR ; OFNB$W ;OPEN THE FILE BCC 270$ ;OK MOV #MSG04,R0 ;CANNOT CREATE TEMP. FILE BR 300$ ; 270$: CALL CCPREP ;DO PREPROCESSING CLOSE$ #AFDB ;CLOSE USER'S SOURCE ; ; OPEN OUTPUT FILES. ; CLR AFDB+F.FNB ;CLEAR FILE ID MOV #AFDB+F.FNB+N.FNAM,R0 ;POINT TO NAME CLR IFDB+F.FNB ;CLEAR FILE ID MOV #IFDB+F.FNB+N.FNAM,R1 ;POINT TO NAME 280$: MOV (R0)+,(R1)+ ;COPY FNB CMP R0,#AFDB+F.FNB+S.FNB ; BLO 280$ ; MOV INT,IFDB+F.FNB+N.FTYP ;THEN SET FILETYPES MOV ASM,AFDB+F.FNB+N.FTYP ; MOV #IFDB,R0 ;GET TEMP FILE FDAT$R ,#R.VAR,#FD.CR ; OFNB$W ; BCC 290$ ; MOV #MSG04,R0 ;CANNOT GET TEMP FILE BR 300$ ; 290$: MOV #AFDB,R0 ;OPEN OUTPUT FILE FDAT$R ,#R.VAR,#FD.CR ; OFNB$W ; BCC 310$ ; MOV #MSG05,R0 ;CANNOT OPEN OUTPUT FILE 300$: CALL CCTTY ;WRITE ERROR TO TI: INC NERRS ;MAKE THE COMPILER EXIT 310$: RETURN ; ;+ ; ** OPT - PROCESS COMMAND OPTIONS ; ; -I RETAIN INTERMEDIATE FILE ; -S RETAIN EXPANDED SOURCE FILE ; -V ECHO BAD SOURCE LINES ; -P PROFILE ; -T GENERATE SYMBOL TABLES ; ; INPUTS: ; R1=OPTION CHARACTER ;- OPT: MOV R0,-(SP) ;MAY NEED THIS REGISTER BIC #BLANK,R1 ;MAKE UPPER CASE CMP R1,#'I ;-I BNE 10$ ;NO INCB IFLAG ;SET FLAG BR 50$ ; 10$: CMP R1,#'V ;-V BNE 20$ ;NO INCB VFLAG ;SET FLAG BR 50$ ; 20$: CMP R1,#'P ;-P BNE 30$ ;NO INCB PFLAG ;SET FLAG BR 50$ ; 30$: CMP R1,#'S ;-S BNE 35$ ;NO INCB SFLAG ;SET FLAG BR 50$ ; 35$: CMP R1,#'T ;-T BNE 40$ ;NO INCB TFLAG ;SET FLAG BR 50$ ; 40$: MOVB R1,MSG06 ;ILLEGAL OPTION MOV #MSG06,R0 ;COMPLAIN CALL CCTTY ; 50$: MOV (SP)+,R0 ;RETURN RETURN ; ;+ ; ** DSPT - BUILD A DSPT ; ; GIVEN AN ASCII FILE NAME STRING, THIS ROUTINE USES THE MIGHTY CSI ; TO BUILD A DSPT IN THE CSI WORK BLOCK. ; WHY FCS REQUIRES A DSPT IS BEYOND ME. ; ; INPUTS: ; R0=PTR TO FILENAME STRING ; ; USES: ; R0 ;- DSPT: MOV R0,CSI+C.CMLD+2 ;SET ADDRESS OF COMMAND LINE 10$: TSTB (R0)+ ;FIND THE LENGTH BNE 10$ ; DEC R0 ; SUB CSI+C.CMLD+2,R0 ; MOV R0,CSI+C.CMLD ;AND PUT IN THE CSI BLOCK CSI$1 #CSI ;DO NASTY WORK BCS 20$ ; CSI$2 ,OUTPUT ; 20$: RETURN ;DONE .END