.title trn$range_q .library 'god$lib:' ;----------------------------------- ; entry pt. TRN$RANGE_Q ; author: ; Gregory C. Lowney -- 2/15/84 ; what is a Range? ; * n:m n;m n#m ; : n: n; n# ; ; :m ;m #m ; what is not a Range? ; *;-m ; arguments: ; p1 = address of descriptor ; p2 = address of quadword to recieve values ; p3 = address of quadword containing defaults (limits) (optional) ; p4 = base (%ref or %val) (optional) $defargs ; format: ; len-used = trn$range_q( line.rt.dx, res.wq.r, [lim.rq.r], [base.rl.x] ) ; registers: ; r2 = base ; r3 = local descr to line ; r4 = ptr into line ; r5 = 1st number ; r6 = 2nd number ; r7 = first star or intermediate char ( ":" or ";" or "#" ) ; r8 = address of scratch longword ; r9 = ???? ; constants: c_blank = ^a/ / c_star = ^a/*/ c_colon = ^a/:/ c_semi = ^a/;/ c_pound = ^a/#/ def_min = 1 def_max = ^x7fffffff def_base = 10 ;----------------------------------- .entry trn$range_q, ^m ; initialize jsb argm_r2 movl #def_base, r2 ; r2 = base movl #def_min, r5 ; r5 = min movl #def_max, r6 ; r6 = max moval -(sp), r8 ; r8 = addr of scratch longword bbc #a_lim, r0, 10$ movq @p_lim(ap), r5 ; get limits 10$: bbc #a_base, r0, 20$ movl p_base(ap), r2 ; get base (%val or %ref) bbc #a_base, r1, 20$ movl (r2), r2 20$: movq @p_line(ap), -(sp) movaq (sp), r3 ; r3 = addr of local descr clrl -(sp) ; sp = addr of xint movab @4(r3), r4 ; r4 = ptr into line ; skip blanks skpc #c_blank, (r3), (r4) ; skip blanks $jeql error movq r0, (r3) movl r1, r4 ; check leading char movl #1, r0 ; (len of lead char) movb (r4), r7 cmpb r7, #c_colon ; if 1st char = colon or semi beql next ; then get 2nd number cmpb r7, #c_semi beql next cmpb r7, #c_pound beql next cmpb r7, #c_star bneq num1 star: incl r4 ; star: leave values at limits, skip star decl (r3) beql 10$ cmpb (r4), #c_colon beql check_2 10$: brw complete num1: ; get first number pushl r2 pushal (r8) pushaq (r3) calls #3, trn$int_l ; call int_l addl2 r0, r4 ; skip used chars tstl r0 bleq error ; error if non-number movl (r8), r5 ; r5 = n1 check_2: movb (r4), r7 ; r7 = char (skip it) cmpb r7, #c_colon ; if semi or colon get 2nd number beql next cmpb r7, #c_semi beql next cmpb r7, #c_pound beql next only1: ; one number movl r5, r6 ; return it in both longwords brb complete next: ; get 2nd number incl r4 ; skip one char (lead or middle) cmpb (r4), #c_star ; if next char star, complete bneq 10$ ; leaving default n2 incl r4 brb complete 10$: cmpb (r4), #c_blank ; if next char blank, def_num2 beql def_num2 movl r4, 4(r3) ; update descriptor addl2 r0, (r3) pushl r2 pushal (r8) pushaq (r3) calls #3, trn$int_l ; call int_l addl2 r0, r4 ; skip used chars tstl r0 blss error ; if error, error beql def_num2 ; if no number, goto def_num2 movl (r8), r6 ; if number, get it, brb complete ; and goto complete def_num2: ; if num2 defaults... cmpb r7, #c_colon beql complete ; def on colon, need do nothing movl #1, r6 ; def on semi is 1 <###> complete: cmpb r7, #c_semi beql 10$ ; goto success if not semi cmpb r7, #c_pound beql 10$ brb success 10$: tstl r6 ; semi conversion blss error ; ;-m is illegal! addl2 r5, r6 ; semi conversion decl r6 ; optional mode line <###> success: movq r5, @p_res(ap) ; move results to arg movq @p_line(ap), r0 ; return length on success subl3 r1, r4, r0 ret error: movl #-1, r0 ; return -1 on error ret ;----------------------------------------------------- .end