
		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

