; $Id: free_all_ptrs.pro,v 1.4 2005/02/03 18:04:12 azuah Exp $
; free_all_ptrs.pro
;
; This procedure descends down the hierarchy of a
; structure or a pointer to a structure and frees
; all of the pointers starting at the lowest point in
; the hierarchy.
;
; Usage:  free_all_ptrs,pState
;
; Written by John Copley and Rob Dimeo (10/31/01)
;
;###############################################################################
;
; LICENSE:
;  The software in this file is written by an employee of 
;  National Institute of Standards and Technology 
;  as part of the DAVE software project.
;
;  The DAVE software package is not subject to copyright protection
;  and is in the public domain. It should be considered as an
;  experimental neutron scattering data reduction, visualization, and
;  analysis system. As such, the authors assume no responsibility
;  whatsoever for its use, and make no guarantees, expressed or
;  implied, about its quality, reliability, or any other
;  characteristic. The use of certain trade names or commercial
;  products does not imply any endorsement of a particular product,
;  nor does it imply that the named product is necessarily the best
;  product for the stated purpose. We would appreciate acknowledgment
;  if the DAVE software is used of if the code in this file is
;  included in another product.
;
;###############################################################################
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
pro analyzeStructure,a,title,lines,flags,descs,flag
help,a,output=helpmsg
ispointer = float(strpos(helpmsg,"POINTER")) ge 0
;
if (ispointer[0]) then begin
;
; We have a pointer.
; Determine whether or not it is a null pointer.
; If it is, free it and return.
	if (ptr_valid(a) eq 0) then begin
    ptr_free,a
		return
	endif
	analyzeStructure,*a,"(*"+title+")",lines,flags,descs,ptrflag
	if (ptrflag eq 0) then begin
		flag=20
		desc="END pointer"
	endif else begin
		flag=2
		desc="Pointer"
	endelse
	if (n_elements(lines) eq 0) then begin
		lines=title
		flags=flag
		descs=desc
	endif else begin
		lines=[lines,title]
		flags=[flags,flag]
		descs=[descs,desc]
	endelse
endif else begin
;
; We have something other than a pointer.
	ispointer = float(strpos(helpmsg,"STRUCT")) ge 0
	if (ispointer[0]) then begin
;
;	We have a structure.
		tags=tag_names(a)
		flagsum=0
		for i=0,n_tags(a)-1 do begin
			analyzeStructure,a.(i),title+"."+tags[i],lines,flags,descs,tagflag
			flagsum=flagsum+tagflag
		endfor
		if (flagsum eq 0) then begin
			flag=10
			desc="END structure"
		endif else begin
			flag=1
			desc="Structure"
		endelse
		if (n_elements(lines) eq 0) then begin
			lines=title
			flags=flag
			descs=desc
		endif else begin
			lines=[lines,title]
			flags=[flags,flag]
			descs=[descs,desc]
		endelse
;
;	We have something other than a structure or a pointer.
	endif else begin
		flag=0
		desc=strcompress(size(a,/n_dimensions))+"-d "+size(a,/tname)
		if (n_elements(lines) eq 0) then begin
			lines=title
			flags=flag
			descs=desc
		endif else begin
			lines=[lines,title]
			flags=[flags,flag]
			descs=[descs,desc]
		endelse
	endelse
endelse

return
end
;;;;;;;
pro free_all_ptrs,state
analyzeStructure,state,"state",lines,flags,descs
nlines=n_elements(lines)
for i=0,nlines-1 do begin
	if (flags[i] ne 0) then $
	if flags[i] eq 2 or flags[i] eq 20 then begin
      execString = 'ptr_free,'+strtrim(string(lines[i]),2)
      r = execute(execString)
    endif
endfor
return
end
