; docformat = 'rst' ; ; NAME: ; updateStructure ; PURPOSE: ; Merge two IDL structures into one, updating or creating tags as appropriate ; ;+ ; :Description: ; Merge two IDL structures into one, updating or creating tags as appropriate ; ; :Categories: ; Disk I/O ; ; :Params: ; base: in, required, type=structure ; An IDL structure to be updated ; update: in, required, type=structure ; An IDL structure which content will be placed in BASE ; ; :Keywords: ; nullUpdate: in, optional, type=boolean, default=0 ; If set, update fields, even if update value is null or zero ; ; :Returns: A structure containing the BASE structure updated with the ; content of the UPDATE structure. Tags are updated or created as appropriate. ; ; :Author: ; B. Carry (OCA) ; ; :Uses: ; updateStructure ; ; :Examples: ; Merge two simple structures:: ; IDL> A = {tag1:1, tag2:'B'} ; IDL> B = {tag2:'C', tag3:3.} ; IDL> merged=updateStructure(A,B) ; IDL> help, merged, /Structure ; ; :History: ; Change History:: ; Original Version written in January 2014, B.Carry (IMCCE) ; 2017 Mar. - B. Carry (OCA) - Keyword NoNull added: no update from null/0 fields ; 2017 Mar. - B. Carry (OCA) - Idl2 added, allow to update arrays in structures ;- function updateStructure, base, update, nullUpdate=nullUpdate COMPILE_OPT hidden, idl2 ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- I -- Initialization And Input Verification -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--I.1-- Presence of Arguments ---------------------------------------------------------------; if N_params() LT 2 then begin message, /INFO, ' Syntax - updated = updateStructure( base, update )' return, -1 endif ;--I.2-- Base and Update Tag Names-------------------------------------------------------------; tagsBase = tag_names(base) tagsUp = tag_names(update) ;--I.3-- Working Copy of Base Structure ------------------------------------------------------; new = base ;print, '----------------------------------------' ;print, '----------------------------------------' ;print, '----------------------------------------' ;print, tagsBase ;print, tagsUp ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--- TAG --- II -- Loop over Tags and Update Values -----------------------; ;-----------------------------------------------------------------------------------------------; ;-----------------------------------------------------------------------------------------------; ;--II.1-- Loop over Tags ---------------------------------------------------------------------; nbTag = n_elements(tagsUp) for kTag=0, nbTag-1 do begin ;--II.2-- Common Tags in Base and Update ---------------------------------------------------; kBase = where( strCmp(tagsUp[kTag], tagsBase) ) kBase = kBase[0] ; print, kTag , ' ', tagsUp(kTag) ;--II.3-- New Tag --> Create Tag -----------------------------------------------------------; if kBase eq -1 then begin ; print, '------> new' ; help, update, /struc ; help, update.(kTag) ; help, update.(kTag), /struc new = create_struct( tagsUp[kTag], update.(kTag), new) tagsBase = tag_names(new) ;--II.4-- Existing Tag --> Check -----------------------------------------------------------; endif else begin ;--II.4.1-- Checking Tag Type (structure or else) kBase = where( strCmp(tagsBase, tagsUp[kTag] ) ) ; ok = execute('s = Size(update.' + tagsUp(kTag) + ')') ; s = size(update.(kTag)) ;--II.4.2-- Tag is a Structure --> Iterate ; if s(s(0)+1) eq 8 then begin if size( update.(kTag), /Type ) eq 8 then begin ; print, '------> sub' ; help, new.(kBase), update.(kTag) ; help, new.(kBase), update.(kTag), /struc ;print, kBase(0), kTag(0) ;print, 'base: '+tagsBase(kBase)+' up: '+tagsUp[kTag] new.(kBase) = call_function('updatestructure', new.(kBase), update.(kTag)) tagsBase = tag_names(new) ;--II.4.3-- Tag is Value --> Update endif else begin ; print, '------> replace' ; help, new.(kBase), update.(kTag) ; help, new.(kBase), update.(kTag), /struc ;print, kBase[0], kTag[0] ;print, 'base: '+tagsBase[kBase]+' up: '+tagsUp[kTag] ;--II.4.3/A-- Update for Null allowed if keyword_set( nullUpdate ) then begin new.(kBase) = update.(kTag) ;--II.4.3/A-- Update for Null Forbidden endif else begin dimB = size(new.(kBase) ) dimU = size(update.(kTag) ) if size( update.(kTag), /Type ) eq 7 then begin if dimB[0] eq 0 and dimU[0] eq 0 then begin if not strCmp(update.(kTag),' ') or not strCmp(update.(kTag),'') then new.(kBase) = update.(kTag) endif else begin if total( abs(dimB[1:dimB[0]]-dimU[1:dimU[0]]) ) eq 0 then begin tot = '' for k=0, total(dimU[1:dimU[0]])-1 do tot += (update.(kTag))[k] if not strCmp( strTrim(tot,2), '') or $ not strCmp( strTrim(tot,2), ' ') then new.(kBase) = update.(kTag) endif endelse endif else begin if dimB[0] eq 0 and dimU[0] eq 0 then begin if update.(kTag) ne 0 then new.(kBase) = update.(kTag) endif else begin if total( abs(dimB[1:dimB[0]]-dimU[1:dimU[0]]) ) eq 0 then begin if total(update.(kTag)) ne 0 then new.(kBase) = update.(kTag) endif endelse endelse endelse ;not necessary? tagsBase = tag_names(new) endelse endelse endfor ;--II.5-- Return Update Structure ----------------------------------------------------------; return, new end