;~C/;/ ;/ $MACRO push mov #@1,-(sp) $ENDM ; $MACRO pop mov (sp)+,#@1 $ENDM / dquote=42 space=40 esc=33 cr=15 PROGRAM Int ;C runtime intercepter FOR macro-11 .psect .main. .mcall gmcr$,dir$,exst$s,call argv: .blkw 30. ;allow 30 args argvp: .word 0 ;pointer to next argv to stuff argc: .word 0 ;assume no args gcmd: gmcr$ data = gcmd + g.mcrb ;address of the data in the buffer. .even .blkw 3 ;just for safety at end of buffer. length: .word 0 ;dsw returned from g mcr line. gp: .word data ;point to the data (getc pointer) moreln: .word flag1: .word flag2: .word ;set if stdout is redirected fa: .word ;file address (of the string) buf: .blkw 3 ;kludge for lseek simulation kludbuf:.asciz " " .even .MAIN: clr argc ;initialize it anyway dir$ #gcmd ;get the command line mov $dsw,length ;and length (or error indicator) IF length GT #0 ;should be pos if a line there. | BEGIN CODE ;so it will reach | mov #argv+2,argvp ;init arg pointer | mov #data,argv ;set first one manually | clr moreln | clr flag2 | clr flag1 | LET r0 = length + #data ;end of cmd line (-> to cr) | IFB -1(r0) = #space | | dec r0 | |...FI | movb #cr,(r0)+ ;extra cr at end (or kill last blank) | movb #cr,(r0)+ | movb #cr,(r0)+ | DO WHILE moreln = #0 | | Call getc ;get char into r0 | | SELECT case r0 of | | | | | CASEB #dquote | | | call getc ;eat up a char | | | call argstart ;start pointer after the " | | | call ungetc ;backup now | | | DO FOREVER | | | | call getc | | | | IFB r0 = #dquote OR r0 = #esc OR r0 = #cr | | | | BREAK | | | | |...FI | | | |...OD | | | IF r0 = #dquote | | | | call delim1 | | | | call getc | | | ELSE | | | | call delim1 | | | |...FI | | BREAK | | | | | CASE #space ;Space | | | call delim1 | | | inc flag1 | | | call getc ;look ahead one for the end | | | call ungetc ;put it back | | | IF r0 = #cr OR r0 = #esc | | | | inc moreln ;done | | | | call delim ;put the delimiter there | | | BREAK | | | |...FI | | BREAK | | | | | CASE #cr ;cr | | | inc moreln | | | call delim1 | | BREAK | | | | | CASE #esc ;esc | | | inc moreln | | | call delim1 | | BREAK | | | | | DEFAULT | | | IF flag1 NE #0 | | | | call argstart | | | | clr flag1 | | | |...FI | | | | | |...ESAC | |...OD | END CODE |...FI IF argc GT #0 | mov argc,r0 ;this is the last parm is null fixup kludge | asl r0 | add #argv-2,r0 | mov (r0),r0 ;get address of beginning of last arg | IFB (r0) = #0 | | dec argc | |...FI |...FI mov argc,r0 mov argv,r1 mov argv+2,r2 mov argv+4,r3 C R0 = main[argc,#argv] ;call user EXST$S R0 getc: ;get a char movb @gp,r0 bic #177600,r0 ;7 bit ascii inc gp ;next pointer rts pc ungetc: ;put back 1 char dec gp rts pc delim1: ;make delim a null and incr argc inc argc delim: ;make delim a null push r0 mov gp,r0 ;get pointer to delim+1 clrb -1(r0) ;and clear delim position pop r0 rts pc argstart: ;set pointer to start of arg push r0 LET r0 = gp - #1 mov r0,@argvp add #2,argvp ;update to next position pop r0 rts pc .end .main