static int checkfill(Symbol* tsym, Datasrc* src) { int i,iscmpd,result; Constant* con; Symbol* original = tsym; result = 1; switch (tsym->subclass) { case NC_ENUM: case NC_OPAQUE: case NC_PRIM: con = srcnext(src); if(src == NULL) { semerror(srcline(src),"%s: malformed _FillValue",original->name); result = 0; } else if(con->nctype != tsym->typ.typecode) result = 0; /* wrong type*/ break; case NC_COMPOUND: if(!issublist(src)) {/* fail on no compound*/ semerror(srcline(src),"Compound constants must be enclosed in {..}"); } srcpush(src); for(i=0;i<listlength(tsym->subnodes);i++) { Symbol* field = (Symbol*)listget(tsym->subnodes,i); result = checkfill(field,src,original); if(!result) break; } srcpop(src); break; case NC_VLEN: if(!issublist(src)) { semerror(srcline(src),"%s: vlen instances in _FillValue must be enclosed in {...}",original->name); result = 0; } else { srcpush(src); while(srcmore(src)) { result = checkfill(tsym->typ.basetype,src,original); if(!result) break; } srcpop(src); } break; case NC_FIELD: /* Braces are optional */ if((iscmpd=issublist(src))) srcpush(src); if(tsym->typ.dimset.ndims > 0) { result = checkarray(tsym->typ.basetype,&tsym->typ.dimset,0,src,original,!TOPLEVEL); } else result = checkfill(tsym->typ.basetype,src,original); if(iscmpd) srcpop(src); break; default: PANIC1("checkfillvalue: unexpected subclass %d",tsym->subclass); } return result; }
int checkfillvalue(Symbol* tvsym, Datalist* filler) { Datasrc* src = datalist2src(filler); int result; ASSERT(tvsym->objectclass == NC_VAR || tvsym->objectclass == NC_TYPE); if(tvsym->objectclass == NC_VAR) { if(tvsym->typ.dimset.ndims > 0) { result = checkarray(tvsym->typ.basetype,&tvsym->typ.dimset,0,src,tvsym,TOPLEVEL); } else result = checkfill(tvsym->typ.basetype,src,tvsym); } else /* NC_TYPE*/ result = checkfill(tvsym,src,tvsym); freedatasrc(src); return result; }
static int checkarray(Symbol* basetype, Dimset* dimset, int index, Datasrc* src, Symbol* original, int toplevel) { int i,result; Symbol* dim = dimset->dimsyms[index]; unsigned int size = dim->dim.declsize; int lastdim = (index == (dimset->ndims - 1)); int isunlimited = (size == 0); result = 1; if(isunlimited) { if(!toplevel) { if(!issublist(src)) { semerror(srcline(src),"UNLIMITED dimension constants (other than top level) must be enclosed in {...}"); result = 0; goto done; } else srcpush(src); } if(lastdim) { while(srcmore(src) && result) { result = checkfill(basetype,src,original); } } else { /*!lastdim*/ while(srcmore(src) && result) { result = checkarray(basetype,dimset,index+1,src,original,toplevel); } } } else { /* bounded*/ if(lastdim) { for(i=0;i<size && result;i++) { result = checkfill(basetype,src,original); } } else { /* !lastdim*/ for(i=0;i<size && result;i++) { result = checkarray(basetype,dimset,index+1,src,original,toplevel); } } } done: return result; }