pro range,pstring,narray,outarr,ier,aoffset
;+
; pro range,pstring,narray,outarr,ier
; atp 16-5-91 
;
; purpose: to parse an input string for ranges and
;	output a list of corresponding subscripts
;	ie array has elements 0....255
;	input string in response to question 'plot which scans?'
;	is '1,2,5,6-200'
;	output array should be [0,1,4,5,6,7,8,9.....198,199]
;	yes the offset is intentional and occurs at end of program 
;	to disable put offset = 0 in variables section	
;
; valid options
;	1,2,3 2-5 * any combination of above
;
; in:	pstring - string containing options
;	narray - number of elements in target array
;
; optional in: offset - the offset for the start of the array - added at end
;	                if not given assumed to be 1
;
; out:	outarr - subscripts selected
;	ier - error code
;		0 = ok , 1 = error out of bounds(non-fatal) ,
;		2 = error out of bounds (fatal)
;                 
; history: Regexp engine written atp 1991
;          upgraded to allow for offset atp 1992
;-
; local variables
;
i = 0;
j = 0;
new_num = 1;
f_num = 1;
lens = 0;
charbuf = ' ';
accbuf = ' ';
skip = 0;
nbuf = 0;
outarr = 0;
start = 0; 
send = ' ';
sendn = 0;
ier = 0;
end_s = 0;
term_char = '|'
offset = 0;
wild_str = ',-'+term_char
if n_elements(aoffset) eq 0 then aoffset = 0;
;
; terminate string 
;
instr = pstring+term_char

if (strpos(instr,'*') ne -1) then begin
	; all subscripts of array
	outarr = indgen(narray)+aoffset;
	if (offset eq 1) then outarr = outarr - 1;
	ier = 0;
	return;
	endif

lens = strlen(instr);
i = 0;
repeat begin
	;print,i
	charbuf = strmid(instr,i,1);
	if (strpos('0123456789',charbuf) ne -1) then begin 
		;a number
		if (new_num eq 1) then accbuf = charbuf else accbuf = accbuf+charbuf
		new_num = 0
		endif else begin
		if (charbuf eq ',') then begin
			;print,'next num
			;next number
			if (new_num eq 1) then skip = 1 
			new_num = 1
			nbuf = fix(accbuf)
                        nbuf = nbuf - aoffset + 1;
			if ((nbuf gt narray) or (nbuf lt 1)) then begin
				; out of bounds
				print,'RANGE: out of bounds',nbuf
				ier = 1
				skip = 1;
				endif
			if (skip eq 0) then begin
	  		   if (f_num eq 1) then begin
				outarr = nbuf 
				f_num = 0; first subscript
				endif else begin
				outarr = [outarr,nbuf]
				endelse
	   		   endif
			;print,'end next num'
			skip = 0	
			endif 

		if (charbuf eq '-') then begin
			;print,'range of numbers
			start = fix(accbuf)
			start = start - aoffset + 1
			if ((start gt narray) or (start lt 1)) then begin
				; out of bounds
				print,'RANGE: start of range out of bounds',start
				ier = 2;
				return;
				endif
			
			end_s = strpos(instr,',',i)
			if (end_s eq -1) then end_s = lens-1
			
			send = strmid(instr,i+1,end_s-i-1)
			
     			for j=0,strlen(send)-1 do if (strpos('0123456789',strmid(send,j,1)) eq -1) then begin 
                        	print,'RANGE: End of range error',send
				ier =2;
				return;
				endif

			sendn = fix(send)
                        sendn = sendn - aoffset + 1

			if ((sendn gt narray) or (sendn lt 1)) then begin
				; out of bounds
				print,'RANGE: End of range out of bounds',sendn
				ier = 2;
				return;
				endif
			
			for j=start,sendn do begin
				if (f_num eq 1) then begin
					outarr = j
					f_num = 0
					endif else begin
					outarr = [outarr,j]
					endelse
				endfor
			new_num = 1
			i = end_s
			;print,'end range num
			endif
			
		if (charbuf eq term_char) then begin
			; end of string 
			; cos i cant be bothered to fix it
			; to work properly
			if (new_num eq 1) then begin 
				; quit straight away
				i = lens
				endif else begin
				;have to output last number
				new_num = 1
				nbuf = fix(accbuf)
				nbuf = nbuf - aoffset + 1
				if ((nbuf gt narray) or (nbuf lt 1)) then begin
					; out of bounds
					print,'RANGE: out of bounds',nbuf
					ier = 1
			       		skip = 1;
					endif
				if (skip eq 0) then begin
	  		   	   if (f_num eq 1) then begin
					outarr = nbuf 
					f_num = 0; first subscript
					endif else begin
					outarr = [outarr,nbuf]
					endelse
	   		   	   endif
				skip = 0	
				endelse
			endif
                if (strpos(wild_str,charbuf) eq -1) then begin
			; a wierd char
			; find next comma
			end_s = strpos(instr,',',i)
			if (end_s eq -1) then end_s = lens-2
			i = end_s
			endif

		endelse
	i = i+1
	endrep until (i gt lens)
;
;
;
if (n_elements(outarr) eq 1) then begin
	if (outarr eq 0) then begin
		outarr = 1
		ier = 2
		endif
	endif else begin
	fred = where(outarr eq 0)
	if (fred(0) ne -1) then begin
		outarr = 1;
		ier = 2;
		endif 
	endelse
outarr = outarr + aoffset - 1 
if (offset eq 1) then outarr = outarr - 1;
end
