.title $$gcmd Parse command line .ident "V02.01" ;+ ; ; Index Parse command line ; ; Usage ; ; Internal ; ; argc = $$gcmd(text, avp, task) ; char *text; /* Command line */ ; char ***avp; /* Gets argv[] location */ ; char *task; /* Task name if nonnull */ ; ; Description ; ; Parse the command line and build the argv[] table. ; ; NOTE: $$gcmd will modify text. argv[] entries will point ; to bytes in text. If not NULL, the task name will become ; argv[0]. ; ; $$gcmd() returns the number of arguments encountered. ; ;- ; Edit history ; V02.00 19-Oct-82 TTC Rework of CS library ; V02.01 24-Jan-83 TTC Fixed error in parameter offsets. ; .psect c$code LF = 12 CR = 15 ESC = 33 SPACE = 40 $$gcmd:: jsr r5,csv$ ; Link environments mov C$PMTR+0(r5),r2 ; r2 -> command line mov r2,r0 ; Get another copy 10$: movb (r0)+,r1 ; Scan each byte to find bic #177600,r1 ; (erase parity bit) beq 20$ ; terminating null cmpb r1,#CR ; or beq 20$ ; cmpb r1,#LF ; or beq 20$ ; cmpb r1,#ESC ; or bne 10$ ; Nope, keep on trying 20$: clrb -(r0) ; Always make a null terminator mov sp,r4 ; Stack will get argv temporarily mov C$PMTR+4(r5),-(sp) ; Push task name first argument ;01 bne next ; There is one, continue tst (sp)+ ; NULL argument, ignore it. ; ; Look for the start of the next argument ; next: clr r3 ; Clear quote flag 10$: movb (r2)+,r0 ; Scan bytes beq savarg ; (exit at null terminator) cmpb r0,#SPACE ; Skipping over blos 10$ ; whitespace cmpb r0,#'' ; Nope, (single) quoted argument? beq 20$ ; Br if so, cmpb r0,#'" ; Not single, is it double? bne 30$ ; Br if not 20$: mov r0,r3 ; Save quote flag br 40$ ; And remember this argument ; ; Perfectly normal, remember the argument start ; 30$: dec r2 ; Unquoted, find start 40$: mov r2,-(sp) ; Save the giblets ; ; We have an argument, scan to the end ; gotarg: 10$: movb (r2)+,r0 ; Look at next byte beq 30$ ; Exit on null tst r3 ; Not null, quoted string bne 20$ ; Yes, special end test cmpb r0,#SPACE ; No, at white space? blos 30$ ; Br if so br 10$ ; Keep scanning 20$: cmpb r0,r3 ; Right flavor quote? bne 10$ ; Nope ; ; At the end of the argument ; 30$: clrb -1(r2) ; Null-trail it ; ; At this point, if the argument was unquoted, we should ; do a directory lookup to find all possible filename matches. ; tstb r0 ; Really at the end? bne next ; No, get the next argument tst r3 ; Can't quit in quoted field bne fatal ; Sorry ; ; All the arguments are on the stack: ; ; r4 -> First arg + 2 (high memory) ; sp -> Last arg (low memory) ; savarg: mov r4,r0 ; Get number of bytes sub sp,r0 ; Stored on the stack mov r0,r2 ; Save for now tst (r0)+ ; Get two more for good luck call $$aloc ; Allocate memory mov r0,@C$PMTR+2(r5) ; Store in user-argument ;01 beq fatal ; Die if no space 10$: mov -(r4),(r0)+ ; Move out the argv cmp r4,sp ; (reversing the order) bhi 10$ ; Until all the arg's are done clr (r0) ; Terminate with a null argument mov r2,r0 ; Reget the number of bytes asr r0 ; Get number of arguments br exit ; And return fatal: mov #-1,r0 ; Parse error exit exit: jmp cret$ ; Return to user. .end