
* scanarg.asm - Read an argument from an AmigaDOS command line.
*
* December 18, 1990 - Ray Burr
* This code may be freely modified and distributed.
*
* History:
*
* - 901218 R. Burr
*   Created.
*

        XDEF    ScanAmigaArg
        XDEF    _ScanAmigaArg

DOUBLE_QUOTE    EQU     '"'
SPACE           EQU     ' '
TAB             EQU     $09
NEWLINE         EQU     $0a
ESCAPE          EQU     $1b
BCPL_ESCAPE     EQU     '*'

*
*
* ScanArg - Process an amiga command line and read an argument.
*
*   A0 - Pointer to string to scan.
*   A1 - Buffer to write processed argument into.
*   A2 - Pointer to first character after the string.
*
* Returns:
*
*   A0 - Pointer to first character after the argument scaned.
*   A1 - Pointer to first character after the argument in the buffer.
*   D0 - Success
*
*   Handles quotes and the '*' escape character.  This routine should read
* a command line nearly the same as the AmigaDOS 1.3 commands do.  One
* exception is that if it is used to read redirection indicators it
* does not handle '<' and '>' as terminating characters.
*   The length of the string returned in the buffer (register A1) will be
* no longer than the length of the argument on the command line.
*

ScanAmigaArg
        move.l  a2,-(sp)

* Skip whitespace.

12$     cmp.l   a2,a0
        bcc     13$
        move.b  (a0)+,d0
        cmp.b   #SPACE,d0
        beq.s   12$
        cmp.b   #TAB,d0
        beq.s   12$
        cmp.b   #NEWLINE,d0
        beq.s   12$

        lea     -1(a0),a0

* Read the argument.

        cmp.l   a2,a0               ;Get the first character.
        bcc     03$
        move.b  (a0)+,d0

        cmp.b   #DOUBLE_QUOTE,d0    ;Check for double quote.
        bne.s   01$

* Process a quoted argument.

08$     cmp.l   a2,a0
        bcc.s   03$
        move.b  (a0)+,d0

        cmp.b   #DOUBLE_QUOTE,d0
        beq.s   03$

        cmp.b   #BCPL_ESCAPE,d0
        bne.s   04$

* Output an escaped character.

        cmp.l   a2,a0               ;Get an escaped character.
        bcc.s   03$
        move.b  (a0)+,d0

        cmp.b   #'N',d0             ;Turn "*N" into a newline character.
        beq.s   05$
        cmp.b   #'n',d0
        bne.s   06$

05$     moveq   #NEWLINE,d0
        bra.s   04$

06$     cmp.b   #'E',d0             ;Turn "*E" into an ESC character.
        beq.s   07$
        cmp.b   #'e',d0
        bne.s   04$

07$     moveq   #ESCAPE,d0

04$     move.b  d0,(a1)+            ;Output the escaped character.
        bra.s   08$

* Loop for reading a non-quoted argument.

02$     move.b  d0,(a1)+

        cmp.l   a2,a0
        bcc.s   03$
        move.b  (a0)+,d0

01$     cmp.b   #SPACE,d0           ;Whitespace terminates the argument.
        beq.s   03$
        cmp.b   #NEWLINE,d0
        beq.s   03$
        cmp.b   #TAB,d0
        bne.s   02$

* Done.

03$     moveq.l #1,d0               ;Success

14$     move.l  (sp)+,a2
        rts

13$     moveq.l #0,d0               ;Failed (No more arguments)
        bra.s   14$


*
* C interface
*
* int ScanAmigaArg(char **cmdline, char **buffer, char *cmdline_end)
*
* cmdline     - The address of a pointer initialized to point to the
*                 argument to be scaned.
* buffer      - The address of a pointer initialized to point to a
*                 buffer for storage of the processed argument.
* cmdline_end - A pointer to the first character after the command line.
*
* Returns zero if it could not read an argument.
*

_ScanAmigaArg
        movem.l a2-a4,-(sp)

        move.l  (4+12)(sp),a3
        move.l  (a3),a0

        move.l  (8+12)(sp),a4
        move.l  (a4),a1

        move.l  (12+12)(sp),a2

        bsr     ScanAmigaArg

        move.l  a0,(a3)
        move.l  a1,(a4)

        movem.l (sp)+,a4-a2
        rts


        END

