home *** CD-ROM | disk | FTP | other *** search
- ********************************************************************************
- * cli_parse.asm - asm replacement for cli_parse - by Talin *
- ********************************************************************************
- ; function
- ; Copy cmdline into argline, expanding and seperating all arguments, with
- ; the pointer to each argument in an array.
-
- ; register usage:
- ; d0 = process BPTR, Command Name BPTR, argument to/from AllocMem
- ; d1 = current parse character, also arg to AllocMem
- ; d2 = lengh of cmdline argument, also 'toupper' version of escape character
- ; d3 = argc
- ; d4 = max argument length
- ; d5 = max slot number
-
- ; a0 = process ptr, command name ptr, end of cmdline ptr
- ; a1 = arglin buffer
- ; a2 = cmdline buffer
- ; a3 = temporary argv array
-
- INCLUDE "exec/types.i"
- INCLUDE "exec/alerts.i"
- INCLUDE "exec/memory.i"
- INCLUDE "libraries/dos.i"
- INCLUDE "libraries/dosextens.i"
- INCLUDE "workbench/startup.i"
-
- xdef __xcli_parse
-
- ; slotsused = xcli_parse(process, cmdline, cmdlen, buffer, maxbuf, slotarray, maxslots)
-
- ; returns 0 if error
- ; note that too many args is not an error -- it simply ignores the extra args.
-
- __xcli_parse: ; (process, cmdlen, cmdline);
- movem.l a2/a3/d2-d5,-(sp) ; push 6 regs = 24 bytes
-
- ;------ get arguments from stack
- move.l 4+24(sp),a0 ; get process pointer
- move.l 8+24(sp),a2 ; get command buffer
- move.l 12+24(sp),d2 ; get command length
- move.l 16+24(sp),a1 ; get destination buffer
- move.l 20+24(sp),d4 ; get size of dest buffer
- move.l 24+24(sp),a3 ; get slot array
- move.l 28+24(sp),d5 ; get max number of slots
- add.l a1,d4 ; d4 = last dest address
- subq.l #1,d4 ; don't count terminating NULL
-
- ;------ find command name
- move.l pr_CLI(a0),d0 ; get pr_CLI field
- lsl.l #2,d0 ; pr_CLI bcpl pointer conversion
- move.l d0,a0 ; a0 <-- process pointer
- move.l cli_CommandName(a0),d0 ; get command name
- lsl.l #2,d0 ; bcpl pointer conversion
-
- ;-- copy command name
- move.l d0,a0 ; a0 <-- commandname
- moveq.l #0,d0 ; BCPL string length = 0
- move.b (a0)+,d0 ; size of command name
- clr.b 0(a0,d0.l) ; terminate the command name
- move.l a0,(a3)+ ; argv[0] <-- command name address
- moveq #1,d3 ; start counting arguments
-
- ;------ null terminate the arguments, eat trailing control characters
- lea 0(a2,d2.l),a0 ; start at end of command line
- stripjunk:
- cmp.b #' ',-(a0) ; if less than space
- dbhi d2,stripjunk ; decrement
-
- clr.b 1(a0) ; null terminate command line.
-
- ;------ start gathering arguments into buffer
- newarg:
- ;-- skip spaces
- move.b (a2)+,d1 ; get next char in command line
- beq.s parmExit ; if zero, no more arguments.
- cmp.b #' ',d1 ; if space
- beq.s newarg ; then loop
- cmp.b #9,d1 ; if tab
- beq.s newarg ; then loop
-
- ;-- check for argument count overflow, if d3 >= d5
- cmp.w d5,d3 ; compare argc with ARGVSLOTS
- bhs.s parmExit ; if overflow, then quit
-
- ;-- push address of the next parameter
- move.l a1,(a3)+ ; argv[argc] = next argbuf loc
- addq.w #1,d3 ; arc++
-
- ;-- process quotes
- cmp.b #'"',d1 ; if it's a quote
- beq.s doquote ; then do special
-
- ;-- copy the parameter in
- cmp.l d4,a1
- bhs.s problem
- move.b d1,(a1)+ ; copy first character to argbuf
-
- nextchar:
- ;------ null termination check
- move.b (a2)+,d1 ; get next arg char
- beq.s parmExit ; if char == '\0' then done
- cmp.b #' ',d1 ; if char == ' ' then
- beq.s endarg ; we're done with this arg.
-
- cmp.l d4,a1
- bhs.s problem
- move.b d1,(a1)+ ; else move cmdline to argbuf
- bra.s nextchar ; and do next char.
-
- endarg:
- cmp.l d4,a1
- bhs.s problem
- clr.b (a1)+ ; null terminate argument
- bra.s newarg ; and get another argument
-
- doquote:
- ;------ process quoted strings
- move.b (a2)+,d1 ; get next char in quoted string
- beq.s parmExit ; if char == '\0' then all done
- cmp.b #'"',d1 ; if char == '"' then done
- beq.s endarg ; do next argument
-
- ;-- '*' is the BCPL escape character
- cmp.b #'*',d1 ; if it's not a '*'
- bne.s addquotechar ; then add it to the arg
-
- move.b (a2)+,d1 ; get character after '*'
- move.b d1,d2 ; convert to upper case
- and.b #$df,d2 ; d2 is temp toupper'd d1
-
- cmp.b #'N',d2 ; check for dos newline char
- bne.s checkEscape
-
- ;-- got a *N -- turn into a newline
- moveq #10,d1 ; d1 <-- newline
- bra.s addquotechar ; add to arg
-
- checkEscape:
- cmp.b #'E',d2 ; check for escape
- bne.s addquotechar ; if not, just add in char
-
- ;-- got a *E -- turn into a escape
- moveq #27,d1 ; else char <-- ESC
-
- addquotechar:
- cmp.l d4,a1
- bhs.s problem
- move.b d1,(a1)+ ; add character to arg
- bra.s doquote ; and continue
-
- parmExit:
- ;------ all done -- null terminate the arguments
- clr.b (a1) ; null terminate last arg
- clr.l (a3) ; clear argv[argc]
-
- move.l d3,d0 ; return number of args in d0
-
- * now, copy argbuf to argv, for argc+1 items
-
- ; move.l sp,a3 ; address of temp argv array
- ;1$ move.l (a3)+,(a1)+ ; copy 1 argument
- ;2$ dbf d3,1$ ; and loop
-
- movem.l (sp)+,a2/a3/d2-d5
- rts
-
- problem:
- moveq #0,d0
- movem.l (sp)+,a2/a3/d2-d5
- rts
-
- end
-