Exemple #1
0
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;
}