pro create_struct, struct, strname, tagnames, tag_descript, DIMEN = dimen, $ CHATTER = chatter, NODELETE = nodelete ;------------------------------------------------------------------------------- compile_opt idl2 if N_params() LT 4 then begin print,'Syntax - CREATE_STRUCT, STRUCT, strname, tagnames, tag_descript,' print,' [ DIMEN = , /CHATTER, /NODELETE ]' return endif if ~keyword_set( chatter) then chatter = 0 ;default is 0 if (N_elements(dimen) eq 0) then dimen = 1 ;default is 1 if (dimen lt 1) then begin print,' Number of dimensions must be >= 1. Returning.' return endif ; For anonymous structure, strname = '' anonymous = 0b if (strlen( strtrim(strname,2)) EQ 0 ) then anonymous = 1b good_fmts = [ 'A', 'B', 'I', 'L', 'F', 'E', 'D', 'J','C','M', 'K' ] fmts = ["' '",'0B','0','0B','0.0','0.0','0.0D0','0L','complex(0)', $ 'dcomplex(0)', '0LL'] arrs = [ 'strarr', 'bytarr', 'intarr', 'bytarr', 'fltarr', 'fltarr', $ 'dblarr', 'lonarr','complexarr','dcomplexarr','lon64arr'] ngoodf = N_elements( good_fmts ) ; If tagname is a scalar string separated by commas, convert to a string array if size(tagnames,/N_dimensions) EQ 0 then begin tagname = strsplit(tagnames,',',/EXTRACT) endif else tagname = tagnames Ntags = N_elements(tagname) ; Make sure supplied tag names are valid. tagname = idl_validname( tagname, /convert_all ) ; If user supplied a scalar string descriptor then we want to break it up ; into individual items. This is somewhat complicated because the string ; delimiter is not always a comma, e.g. if 'F,F(2,2),I(2)', so we need ; to check positions of parenthesis also. sz = size(tag_descript) if sz[0] EQ 0 then begin tagvar = strarr( Ntags) temptag = tag_descript for i = 0, Ntags - 1 do begin comma = strpos( temptag, ',' ) lparen = strpos( temptag, '(' ) rparen = strpos( temptag, ')' ) if ( comma GT lparen ) and (comma LT Rparen) then pos = Rparen+1 $ else pos = comma if pos EQ -1 then begin if i NE Ntags-1 then message, $ 'WARNING - could only parse ' + strtrim(i+1,2) + ' string descriptors' tagvar[i] = temptag goto, DONE endif else begin tagvar[i] = strmid( temptag, 0, pos ) temptag = strmid( temptag, pos+1) endelse endfor DONE: endif else tagvar = tag_descript ; create string array for IDL statements, to be written into ; 'temp_'+strname+'.pro' pro_string = strarr (ntags + 2) if (dimen EQ 1) then begin pro_string[0] = "struct = { " + strname + " $" pro_string[ntags+1] = " } " endif else begin dimen = long(dimen) ;Changed to LONG from FIX Mar 95 pro_string[0] = "struct " + " = replicate ( { " + strname + " $" pro_string[ntags+1] = " } , " + string(dimen) + ")" endelse tagvar = strupcase(tagvar) for i = 0, ntags-1 do begin goodpos = -1 for j = 0,ngoodf-1 do begin fmt_pos = strpos( tagvar[i], good_fmts[j] ) if ( fmt_pos GE 0 ) then begin goodpos = j break endif endfor if goodpos EQ -1 then begin print,' Format not recognized: ' + tagvar[i] print,' Allowed formats are :',good_fmts stop,' Redefine tag format (' + string(i) + ' ) or quit now' endif if fmt_pos GT 0 then begin repeat_count = strmid( tagvar[i], 0, fmt_pos ) if strnumber( repeat_count, value ) then begin fmt = arrs[ goodpos ] + '(' + strtrim(fix(value), 2) + ')' endif else begin print,' Format not recognized: ' + tagvar[i] stop,' Redefine tag format (' + string(i) + ' ) or quit now' endelse endif else begin ; Break up the tag descriptor into a format and a dimension tagfmts = strmid( tagvar[i], 0, 1) tagdim = strtrim( strmid( tagvar[i], 1, 80),2) if strmid(tagdim,0,1) NE '(' then tagdim = '' fmt = (tagdim EQ '') ? fmts[goodpos] : arrs[goodpos] + tagdim endelse if anonymous and ( i EQ 0 ) then comma = '' else comma = " , " pro_string[i+1] = comma + tagname[i] + ": " + fmt + " $" endfor ; Check that this structure definition is OK (if chatter set to 1) if keyword_set ( Chatter ) then begin ans = '' print,' Structure ',strname,' will be defined according to the following:' temp = repchr( pro_string, '$', '') print, temp read,' OK to continue? (Y or N) ',ans if strmid(strupcase(ans),0,1) eq 'N' then begin print,' Returning at user request.' return endif endif ; --- Determine if a file already exists with same name as temporary file tempfile = 'temp_' + strlowcase( strname ) while file_test( tempfile + '.pro' ) do tempfile = tempfile + 'x' ; ---- open temp file and create procedure ; ---- If problems writing into the current directory, try the HOME directory cd,current= prodir cdhome = 0 openw, unit, tempfile +'.pro', /get_lun, ERROR = err if (err LT 0) then begin prodir = getenv('HOME') tempfile = prodir + path_sep() + tempfile while file_test( tempfile + '.pro' ) do tempfile = tempfile + 'x' openw, unit, tempfile +'.pro', /get_lun, ERROR = err if err LT 0 then message,'Unable to create a temporary .pro file' cdhome = 1 endif name = file_basename(tempfile) printf, unit, 'pro ' + name + ', struct' printf,unit,'compile_opt hidden' for j = 0,N_elements(pro_string)-1 do $ printf, unit, strtrim( pro_string[j] ) printf, unit, 'return' printf, unit, 'end' free_lun, unit ; If using the HOME directory, it needs to be included in the IDL !PATH if cdhome then cd,getenv('HOME'),curr=curr resolve_routine, name Call_procedure, name, struct if cdhome then cd,curr if keyword_set( NODELETE ) then begin message,'Created temporary file ' + tempfile + '.pro',/INF return endif else file_delete, tempfile + '.pro' return end ;pro create_struct