Viewing contents of file '../idllib/astron/contrib/varosi/vlib/allpro/align_struct.pro'
pro align_struct, struct_name, struct, Max_Field_Size, struct_size, Lun_out
;+
; NAME:
; ALIGN_STRUCT
; PURPOSE:
; Check an IDL structure for standard memory alignment of fields,
; insert any byte padding required to align fields on size boundaries,
; write out new code to define the aligned version of structure.
; CATEGORY:
; Structures
; CALLING SEQUENCE:
; align_struct, structure_name
; examples:
; align_struct, "fdq_sdf"
; INPUTS:
; structure_name = string giving the structure name
; as known by IDL (help,/struct,variable).
;
; inputs/outputs used recursively:
; struct = the structure variable currently analyzed.
; Max_Field_Size = size of the largest field found in structure.
; struct_size = total size of all fields in structure.
; Lun_out = Logical unit number for writing .PRO code.
;
; SIDE EFFECTS:
; "structure_name"_ST_AL.PRO is created (IDL function code).
; PROCEDURE:
; Strategy is to call align_struct recursively.
;
; otherwise the field type and size is used to construct IDL definition,
; which is then concatenated with the other IDL definitions,
;
; MODIFICATION HISTORY:
; written 1990 Frank Varosi STX @ NASA/GSFC
;-
if N_tags( struct ) LE 0 then begin
s = size( struct_name )
if ( s(s(0)+1) NE 7 ) then begin
message,"specify STRUCTURE NAME in first arg.",/CONTIN
return
endif
struct_name = strupcase( struct_name )
status = execute( "struct=replicate({" + struct_name + "},1)" )
func_struct = struct_name + "_ST_AL"
func_code = [ "function " + func_struct + ", Nstruct" ,$
" " ,$
" common " + func_struct + ", defined" ,$
" " ,$
" if N_elements( defined ) NE 1 then begin" ,$
" " ]
struct_align = strmid( struct_name, 0, 12 ) + "_AL"
func_end = [ " defined = 1 " ,$
" endif" ,$
" " ,$
" if N_elements( Nstruct ) NE 1 then Nstruct = 1" ,$
" " ,$
"return, replicate( {" + struct_align + "}, Nstruct )",$
"end" ]
Ncode = N_elements( func_code )
file_struct = func_struct + ".PRO"
openw, Lun_out, file_struct, /get_Lun
message, "creating file " + file_struct, /CONTIN
for i=0,Ncode-1 do printf, Lun_out, func_code(i)
print," Structure Name Size Max Field Size"
endif
Tags = Tag_Names( struct )
Ntag = N_tags( struct )
Max_Field_Size = 1
struct_size = 0
struct_def = ""
for t=0,Ntag-1 do begin
s = size( struct.(t) )
N_elem = s( s(0)+2 )
N_els = strtrim( N_elem, 2 )
Tag_Name = Tags(t)
Field_Type = s( s(0)+1 )
if (Field_Type EQ 8) then begin
bytpad = struct_size MOD 8 ;req. align. for structs?
if (bytpad NE 0) then begin
pn = strtrim( t, 2 )
Nb = strtrim( bytpad, 2 )
pad_def = "PAD_" + pn + ": bytarr( " + Nb + " )"
struct_def = [ struct_def, pad_def ]
struct_size = struct_size + bytpad
print, "Post-Padding", bytpad, " bytes",$
FORM="(A15,I8,(A))"
endif
align_struct, Tags(t), struct.(t), MaxF_siz, ST_siz, Lun_out
if (N_elem GT 1) then begin
Tag_def = ": replicate( " + Tag_Name + $
", " + N_els + " )"
endif else Tag_def = ": " + strlowcase( Tag_Name )
struct_def = [ struct_def , Tag_Name + Tag_def ]
struct_size = struct_size + ST_siz * N_elem
Max_Field_Size = Max_Field_Size > MaxF_siz
endif else begin
CASE Field_Type OF
1: BEGIN
Field_Size = 1
if (N_elem EQ 1) then Tag_def = ": 0B" $
else Tag_def = ": bytarr( " + N_els + " )"
END
2: BEGIN
Field_Size = 2
if (N_elem EQ 1) then Tag_def = ": 0" $
else Tag_def = ": intarr( " + N_els + " )"
END
3: BEGIN
Field_Size = 4
if (N_elem EQ 1) then Tag_def = ": 0L" $
else Tag_def = ": Lonarr( " + N_els + " )"
END
4: BEGIN
Field_Size = 4
if (N_elem EQ 1) then Tag_def = ": 0.0" $
else Tag_def = ": fltarr( " + N_els + " )"
END
5: BEGIN
Field_Size = 8
if (N_elem EQ 1) then Tag_def = ": 0.D0" $
else Tag_def = ": dblarr( " + N_els + " )"
END
6: BEGIN
Field_Size = 8
if (N_elem EQ 1) then Tag_def = ": complex(0)" $
else Tag_def = ": complexarr( " + N_els + " )"
END
7: BEGIN
Tag_def = ""
Tag_Name = ""
END
else: BEGIN
Tag_def = ""
Tag_Name = ""
END
ENDCASE
bytpad = struct_size MOD Field_Size
if (bytpad NE 0) then begin
pn = strtrim( t, 2 )
Nb = strtrim( bytpad, 2 )
pad_def = "PAD_" + pn + ": bytarr( " + Nb + " )"
struct_def = [ struct_def, pad_def ]
struct_size = struct_size + bytpad
endif
struct_def = [ struct_def , Tag_Name + Tag_def ]
struct_size = struct_size + Field_Size * N_elem
Max_Field_Size = Max_Field_Size > Field_Size
endelse
endfor
bytpad = struct_size MOD Max_Field_Size
if (bytpad NE 0) then begin
Nb = strtrim( bytpad, 2 )
pad_end = "PAD_END" + ": bytarr( " + Nb + " )"
struct_def = [ struct_def, pad_end ]
struct_size = struct_size + bytpad
endif
;write out the aligned structure definition IDL code:
struct_namLc = strlowcase( struct_name )
struct_name = strmid( struct_name, 0, 12 ) + "_AL"
print, struct_name, struct_size, Max_Field_Size, FORM="(A15,I8,I8)"
structure = " " + struct_namLc + " = { " + struct_name
blanks = replicate( 32B, 80 )
Lpad = strpos( structure, "{" ) + 1
struct_def = string( blanks(0:Lpad) ) + struct_def(1:*)
structure = [ structure, struct_def ]
Lpad = strlen( structure )
Lpad = (max( Lpad ) - Lpad) < 70
Nstr = N_elements( structure )
for i=0,Nstr-2 do structure(i) = structure(i) + $
string( blanks(0:Lpad(i)) ) + ", $"
structure(Nstr-1) = structure(Nstr-1) + $
string( blanks(0:Lpad(i)+4) ) + "}"
for i=0,Nstr-1 do printf, Lun_out, structure(i)
printf, Lun_out, ""
Nend = N_elements( func_end )
if (Nend GT 0) then begin
for i=0,Nend-1 do printf, Lun_out, func_end(i)
free_Lun, Lun_out
message,"finished aligned structure code for "+struct_name,/CONT
endif
return
end