pro spdf_str_element,struct,tagname,value, $
ADD_REPLACE = add_rep, $
DELETE = delete, $
CLOSEST = closest, $
SUCCESS = success, $
VALUE = value2, $
INDEX = index
pos = strpos(tagname,'.')
if pos ge 0 then begin
base_name = strupcase( strmid(tagname,0,pos) )
ext = strmid(tagname,pos+1,100)
endif else base_name=strupcase(tagname)
success = 0
if size(/type,struct) ne 8 then index = -2 else begin
tags = tag_names(struct)
index = (where(base_name eq tags,count))[0]
if count gt 1 then dprint,'More than one exact match of '+base_name+' found.'
if count eq 0 and keyword_set(closest) then begin
p = intarr(n_elements(tags))
for i=0,n_elements(tags)-1 do p[i] = strpos(base_name,tags[i])
mx = max((p eq 0) * strlen(tags),index)
if mx eq 0 then index=-1
w = where(p eq 0,count)
if count ge 2 then $
dprint,'Warning: multiple close matchs of '+base_name+' found:'+string(/print,tags[w])
if count eq 1 then dprint,'Near match of '+base_name+' found: '+tags[index]
endif
endelse
n = index
if pos ge 0 then begin
if index ge 0 then new_struct= struct.(index)
spdf_str_element,new_struct,ext,value, index=i, success=success, $
add_rep=add_rep,delete=delete
if keyword_set(add_rep) then $
spdf_str_element,struct,base_name,new_struct,/add_rep
index = [index,i]
return
endif
if keyword_set(add_rep) and (n_elements(value) eq 0) then delete=1
if keyword_set(delete) then begin
delete_var = n
add_rep = n ge 0
endif else delete_var=-1
if keyword_set(add_rep) or keyword_set(delete) then begin
if n_elements(struct) gt 1 then begin
replace = keyword_set(delete)
replace = replace or ( n lt 0 )
if not replace then begin
s1 = size(struct.(n))
s2 = size(value)
w = where(s1 ne s2,diff_type)
replace = replace or (diff_type ne 0)
endif
if not replace and (size(/type,value) eq 8) then begin
new_tags= tag_names_r(value[0],type=new_dt)
old_tags= tag_names_r(struct[0].(n),type=old_dt)
replace = n_elements(new_tags) ne n_elements(old_tags)
w = where(new_tags ne old_tags,diff_type)
replace = replace or (diff_type ne 0)
w = where(new_dt ne old_dt,diff_type)
replace = replace or (diff_type ne 0)
endif
if replace then begin
s0 = struct[0]
dim_value = dimen(value)
ndim_value = n_elements(dim_value) * keyword_set(dim_value)
if ndim_value gt 1 then begin
last_dim = dim_value[ndim_value-1]
if last_dim ne n_elements(struct) then message, 'Array dimension mismatch'
dim = dim_value[0:ndim_value-2]
V0 = reform(value,product(dim,/preserve),last_dim)
V0 = reform( v0[*,0], dim)
endif else if ndim_value eq 1 then v0 = value[0]
spdf_str_element,/add,s0,base_name,v0,delete=delete,index=nj
new_struct = make_array(value=s0,dim=dimen(struct))
ntags = n_tags(new_struct)
tags = tag_names(new_struct)
for i=0,ntags-1 do begin
spdf_str_element,s0,tags[i],index=j
if i eq nj then new_value = value else new_value=struct.(j)
new_struct.(i) = new_value
endfor
struct=new_struct
endif else begin
struct.(n)=value
endelse
return
endif
case n of
-2: if n_elements(value) ne 0 then $
struct = create_struct(idl_validname(/convert_all,base_name),value)
-1: if n_elements(value) ne 0 then $
struct = create_struct(struct,idl_validname(/convert_all,base_name),value)
else: begin
replace = keyword_set(delete)
replace = replace or (size(/type,value) eq 8)
if not replace then begin
s1 = size(struct.(n))
s2 = size(value)
w = where(s1 ne s2,diff_type)
replace = replace or (diff_type ne 0)
endif
if replace then begin
ntags = n_elements(tags)
new_struct = 0
for i=0,ntags-1 do begin
if i ne delete_var then begin
if i eq n then new_value=value else new_value=struct.(i)
if not keyword_set(new_struct) then $
new_struct = create_struct(idl_validname(/convert_all,tags[i]),new_value) $
else new_struct = create_struct(new_struct,idl_validname(/convert_all,tags[i]),new_value)
endif
endfor
struct = new_struct
endif else struct.(n)=value
endelse
endcase
success = 1
if n lt 0 then index = n_tags(struct)-1
endif else begin
if n ge 0 then begin
value = struct.(n)
value2 = value
success=1
endif
endelse
return
end