bool CalcStructSize( sym_id sd ) { //=================================== // determine the size of a structure // return true if recursion detected, false otherwise sym_id map; sym_id field; sym_id saved_link; intstar4 size; intstar4 total_size; // in case size of structure already calculated if( sd->u.sd.size != 0 ) return( false ); saved_link = sd->u.sd.link; if( saved_link == sd ) { return( true ); // recursion detected! } sd->u.sd.link = sd; // to protect against recursion total_size = 0; field = sd->u.sd.fl.sym_fields; while( field != NULL ) { size = 0; if( field->u.fd.typ == FT_UNION ) { map = field->u.fd.xt.sym_record; while( map != NULL ) { if( CalcStructSize( map ) ) { sd->u.sd.link = saved_link; return( true ); // recursion detected } if( size < map->u.sd.size ) { size = map->u.sd.size; } map = map->u.sd.link; } } else { if( field->u.fd.typ == FT_STRUCTURE ) { if( StmtSw & SS_DATA_INIT ) { if( field->u.fd.xt.record->fl.fields == NULL ) { StructErr( SP_UNDEF_STRUCT, field->u.fd.xt.sym_record ); } } if( CalcStructSize( field->u.fd.xt.sym_record ) ) { sd->u.sd.link = saved_link; return( true ); // recursion detected } } size = _FieldSize( field ); if( field->u.fd.dim_ext != NULL ) { size *= field->u.fd.dim_ext->num_elts; } } total_size += size; field = field->u.fd.link; } sd->u.sd.size = total_size; sd->u.sd.link = saved_link; // restore saved link return( false ); }
static void VarList( void ) { //========================= // Process one variable list in a DATA statement. OPR last_opr; OPR opr; int do_level; itnode *last_node; do_level = 0; last_opr = FindSlash( &last_node ); while( CITNode != last_node ) { if( AError ) break; if( RecTrmOpr() && ( CITNode != ITHead ) ) { --do_level; FinishImpDo(); } else if( StartImpDo() ) { ++do_level; } else if( ReqName( NAME_VAR_OR_ARR ) ) { InitVar = LkSym(); if( InitVar->u.ns.u1.s.typ == FT_STRUCTURE ) { // make sure structure size is calculated - normally // structure size is calculated by StructResolve() which // is not called until the first executable statement CalcStructSize( InitVar->u.ns.xt.sym_record ); } CkFlags(); opr = CITNode->opr; ProcDataExpr(); CITNode->opr = opr; ListItem(); if( !RecTrmOpr() ) { ReqComma(); } } else { AdvanceITPtr(); AError = true; break; } } if( AError ) { while( do_level != 0 ) { // clean up hanging do entrys TermDo(); --do_level; } } else { CITNode->opr = last_opr; ReqDiv(); } }