
                INCLUDE "call.i"

EOL             equ     $0a             CLI command activator

*-------------------------------------------------------*
*
*  - __main -
*
*  Function:    Convert commandline to argv and argc, then call main() with them
*
*  Input:       4(a7).l Pointer to commandline
*
*  Output:      d0.l    Return value (as can be used in script files)
*
*

                csect   text,0,0,1,2

                Func    __main
                movem.l d2/d3/a2,-(a7)

*--     Insert terminators, get pointers, find argc

                move.l  a7,a2                   Keep stackpointer
                move.l  16(a7),a0               Get begin
                lea.l   0(a7),a1                Remember first argv for reverse action
                moveq.l #0,d3                   Argc (program name)

SearchNextSpace move.b  (a0),d0                 Search *argv
                cmp.b   #' ',d0                 Spaces are delimiters
                bhi.s   ArgvFound               Any printable but SP causes an *argv
                bcs.s   FinalTerm               Any control causes a leave loop
KillSpace       clr.b   (a0)+                   No spaces allowed
                bra.s   SearchNextSpace
ArgvFound       cmp.b   #'"',d0                 Entry embedded spaces?
                beq.s   SpecialFound            Yes, special search action
                move.l  a0,-(a7)                No, normal, push a *argv
                addq.l  #1,d3                   ++Argc
SearchSpace     cmp.b   #' ',(a0)               Now search for end
                beq.s   KillSpace               End found, search next *argv
                bcs.s   FinalTerm               Very end found; leave
                addq.l  #1,a0                   Still inside argument,
                bra.s   SearchSpace             So keep searching for delimiter
SpecialFound    addq.l  #1,a0                   Skip special entry code char
                move.l  a0,-(a7)                Push a *argv
                addq.l  #1,d3                   ++Argc
SearchSpecial   move.b  (a0),d0                 Only '"' and '\0' are delimiters (EOL?)
                beq.s   FinalTerm               Very end found; leave
                cmp.b   #'"',d0                 Special delimiter?
                beq.s   KillSpace               Yes, act like space found
                cmp.b   #EOL,d0                 @ We look for EOL too
                beq.s   FinalTerm               @ And leave on meeting it
                addq.l  #1,a0                   No, still inside argument,
                bra.s   SearchSpecial           So keep searching for delimiter
FinalTerm       clr.b   (a0)                    Now, here is my story:

* If the command line does not contain any embedded space arguments,
* FinalTerm deletes the closing control, normally a LF. However, you are
* allowed to embed all controls but '\0' in embedded space arguments. If
* you do not close this argument with '"', but instead gives an EOL, this
* EOL takes part of this argument. In this version, we leave the loop on
* finding it. (@)

*--     The argv-array is in reversed order, so do something about it

                move.l  a7,a0                   Get begin, end is already in a1
                move.l  d3,d2                   Get number of pointers
                lsr.l   #1,d2                   Argc/2 we exchange two at a time
                bra.s   ExchPointers1
ExchPointers0   move.l  -(a1),d0
                move.l  (a0),d1
                move.l  d0,(a0)+
                move.l  d1,(a1)
ExchPointers1   dbra    d2,ExchPointers0

*--     For some reasons its nice to have a long aligned stackpointer.

                move.l  a7,d1                   Argv
                move.l  a7,d0                   Prepare for long line up
                lsr.l   #2,d0                   We look for a carry
                bcc.s   LongAlined              Already long
                subq.l  #2,a7                   Make a7 long aligned
LongAlined      move.l  d1,-(a7)                Push *argv[]
                move.l  d3,-(a7)                Push argc
                Call    _main                   main()
                move.l  a2,a7                   Restore stackpointer
                movem.l (a7)+,d2/d3/a2
                rts

                END

