;
; this section of code should parse the string used to dump the data
;
	.title 	parse_string -- parse the macro definition string

	$tpadef

;
; another psect for expansion of current macro definition
;
	.psect	special,pic,usr,ovr,rel,gbl,shr,noexe,rd,wrt,novec,long

sp_addr:
	.blkb	65535

	.psect	$local,rd,wrt,noexe,pic

errlen:  .blkw 1
msgbuf:  .long 255
         .long msgadr

msgadr:  .blkb 255
save:	.blkl	1
save_rp:
	.blkl	1
	
sp_count:
	.blkl	1

special:
	.long	0
	.long	sp_addr
temp:
	.long 	32768
	.long 	tmp_addr
tmp_addr:
	.blkb	32768

repeat:
	.long	32768				; initial length 0
	.long	rep_addr
rep_addr:
	.blkb	32768

rep_cnt:
	.blkl	1

	$init_state		dmpsta,dmpkey

	$state	begin
	$tran		tpa$_eos,tpa$_exit,dump_char
	$tran		tpa$_alpha,begin,add_char
	$tran		tpa$_digit,next,add_count

	$state	next
	$tran		tpa$_digit,next,add_count
	$tran		tpa$_alpha,begin,dupl_char
	$tran		'(',repeat_state,store_repeat

	$state	repeat_state
	$tran		tpa$_eos,tpa$_fail
	$tran		tpa$_digit,repeat1_state,add_count
	$tran		tpa$_alpha,repeat_state,add_rep
	$tran		')',begin,do_repeat

	$state	repeat1_state
	$tran		tpa$_eos,tpa$_fail
	$tran		tpa$_digit,repeat1_state,add_count
	$tran		tpa$_alpha,repeat_state,dupl_rep
	
	$end_state

	.entry parse_string,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
	
	clrl	special
	clrl	save
	clrl	rep_cnt
	subl2	#tpa$k_length0,sp
	moval	(sp),r2
	movl	#tpa$k_length0,tpa$l_count(r2)
	clrb	tpa$b_mcount(r2)
	movaq	@4(ap),r0
	cvtwl	(r0),tpa$l_stringcnt(r2)
	moval	@4(r0),tpa$l_stringptr(r2)
;+
;	Call LIB$TPARSE to process the data and return
;-
	pushal	dmpkey
	pushal	dmpsta
	pushal	(r2)
	calls	#3,g^lib$tparse
15$:	movl	tpa$l_stringcnt(r2),@8(ap)
	ret

	.entry	store_repeat,^m<r2,r3,r4,r5>
	movl	save,save_rp
	clrl	save
	movl	#1,r0
	ret

	.entry	add_rep,^m<r2,r3,r4,r5>
	moval	tmp_addr,r5
	addl2	rep_cnt,r5
	movb	tpa$b_char(ap),(r5)
	incl	rep_cnt
	movl	#1,r0
	ret

	.entry	dupl_rep,^m<r2,r3,r4,r5>
	pushab	tpa$l_char(ap)				; get character
	pushal	save					; get rep count
	pushaq	repeat					; get temp string
	calls	#3,g^str$dupl_char			; duplicate it
	blbs	r0,10$					; success?
	pushl	r0					; no, die
        calls   #1,give_error
        clrl    r0
        ret

10$:	moval	tmp_addr,r5
	addl2	rep_cnt,r5
	movc3	save,rep_addr,(r5)			; yes, append
	addl2	save,rep_cnt
	clrl	save
	movl	#1,r0
	ret

	.entry	do_repeat,^m<r2,r3,r4,r5>

30$:	moval	sp_addr,r5
	addl2	special,r5
	movc3	rep_cnt,tmp_addr,(r5)			; concantenate until
							; enough done
	addl2	rep_cnt,special
20$:	decl	save_rp					; decrement repeat cnt
	tstl	save_rp					; done yet???
	bneq	30$					; no, continue
	movl	#1,r0
	ret

	.entry	add_char,^m<r2,r3,r4,r5>
	moval	sp_addr,r5				; get address
	addl2	special,r5
	movb	tpa$b_char(ap),(r5)			; store 1 char
	incl	special
	ret

	.entry	dump_char,^m<r2,r3,r4,r5>		; used to debug
	moval	sp_addr,r5
	addl2	special,r5
	movb	#0,(r5)					; set to zero
	movl	#1,r0					; expansion buffer
	ret

	.entry	add_count,^m<r2,r3,r4,r5>
	subl3	#48,tpa$b_char(ap),r2			; save repeat 
	mull3	#10,save,save
	addl2	r2,save
	movl	#1,r0
	ret						;   count

	.entry	dupl_char,^m<r2,r3,r4,r5>
	pushab	tpa$l_char(ap)				; get character
	pushal	save					; get rep count
	pushaq	temp					; get temp string
	calls	#3,g^str$dupl_char			; duplicate it
	blbs	r0,40$					; success?
	pushl	r0					; no, die
        calls   #1,give_error
        clrl    r0
        ret

40$:	moval	sp_addr,r5
	addl2	special,r5
	movc3	save,tmp_addr,(r5)			; yes, append
	addl2	save,special
	clrl	save
	movl	#1,r0
	ret

;
; give out error messages
;
        .entry  give_error,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
        $getmsg_s  msgid=4(ap),-
                   msglen=errlen,-
                   bufadr=msgbuf
        pushaq  msgbuf
        pushaq  msgbuf
        calls   #1,g^str$trim
        pushaq  msgbuf
        calls   #1,g^lib$put_output

        movl    #1,r0
        ret
        
	.end
