Esempio n. 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;
}
Esempio n. 2
0
static void
genbin_arraydatar(Symbol* vsym,
		  Bytebuffer* memory,
		  nciter_t iter,
		  Iterodom* iterodom,
	          int index)
{
    int i;
    int rank = iterodom->rank;
    int lastdim = (index == (rank - 1)); /* last dimension*/
    int firstdim = (index == 0);
    int declsize = odom->dims[index].declsize;
    int isunlimited = (declsize == 0);
    Symbol* basetype = vsym->typ.basetype;
    Datalist* fillsrc = vsym->var.special._Fillvalue;
    Constant* con;

    ASSERT(index >= 0 && index < rank);
    odom->dims[index].index = 0; /* reset*/

    if(isunlimited) {
	Constant* con;
        if(!firstdim) {
	    if(!issublist(src)) {
	        semerror(srcline(src),"Unlimited data must be enclosed in {..}");
	        return;
	    }
	    srcpush(src); /* enter the unlimited data */
	}
	while((con=srcpeek(src))!=NULL) {
	    if(lastdim) {
                genbin_data(basetype,src,fillsrc,memory);
	    } else {
                genbin_arraydatar(vsym,src,odom,index+1,
                                               checkpoint,memory);
	    }
	    odom->dims[index].index++;
	    if(docheckpoint) {
                closure->putvar(closure,odom,memory);
	    }
	}
        odom->dims[index].datasize = odom->dims[index].index;
	if(!firstdim) srcpop(src);
    } else { /* !isunlimited*/
	for(i=0;i<declsize;i++) {
	    con = srcpeek(src);
            if(lastdim) {
                genbin_data(basetype,src,fillsrc,memory);
            } else { /* ! lastdim*/
               (void)genbin_arraydatar(vsym,src,odom,
                                              index+1,checkpoint,memory);
            }
            odom->dims[index].index++;
            if(docheckpoint) {
                closure->putvar(closure,odom,memory);
            }
	}
    }
}
Esempio n. 3
0
static void
genbin_data(Symbol* tsym, Datasrc* datasrc, Datalist* fillsrc,
		Bytebuffer* memory)
{
    int usecmpd;
    Constant* con = srcpeek(datasrc);
    if(con == NULL || con->nctype == NC_FILLVALUE) {
	srcnext(datasrc);
	genbin_fillvalue(tsym,fillsrc,datasrc,memory);
	return;
    }

    switch (tsym->subclass) {

    case NC_ENUM:
    case NC_OPAQUE:
    case NC_PRIM:
	if(issublist(datasrc)) {
	    semerror(srcline(datasrc),"Expected primitive found {..}");
	}
	genbin_primdata(tsym,datasrc,fillsrc,memory);
	break;

    case NC_COMPOUND:
	genbin_compound(tsym,datasrc,fillsrc,memory);
	break;

    case NC_VLEN: {
        Constant* cp;
        nc_vlen_t ptr;
        if(!issublist(datasrc)) {
	    semerror(srcline(datasrc),"Vlen data must be enclosed in {..}");
        }
        cp = srcnext(datasrc);
        /* generate the nc_vlen_t instance*/
        ptr.p = vlendata[cp->value.compoundv->vlen.uid].data;
        ptr.len = vlendata[cp->value.compoundv->vlen.uid].count;
        bbAppendn(memory,(char*)&ptr,sizeof(ptr));
        } break;

    case NC_FIELD:
	/* enclose in braces if and only if field is an array */
	usecmpd = (issublist(datasrc) && tsym->typ.dimset.ndims > 0);
	if(usecmpd) srcpush(datasrc);
	if(tsym->typ.dimset.ndims > 0) {
            genbin_fieldarray(tsym->typ.basetype,datasrc,&tsym->typ.dimset,0,memory);
	} else {
	    genbin_data(tsym->typ.basetype,datasrc,NULL,memory);
	}
	if(usecmpd) srcpop(datasrc);
	break;

    default: PANIC1("genbin_data: unexpected subclass %d",tsym->subclass);
    }
}
Esempio n. 4
0
static nc_type
inferattributetype1(Datasrc* src)
{
    nc_type result = NC_NAT;
    /* Recurse down any enclosing compound markers to find first non-fill "primitive"*/
    while(result == NC_NAT && srcmore(src)) {
	if(issublist(src)) {
	    srcpush(src);
	    result = inferattributetype1(src);
	    srcpop(src);
	} else {	
	    Constant* con = srcnext(src);
	    if(isprimplus(con->nctype)) result = con->nctype;
	    /* else keep looking*/
	}
    }
    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;
}
void
f77data_array(Symbol* vsym,
		  Bytebuffer* databuf,
		  Datasrc* src,
		  Odometer* odom,
	          int index,
		  Datalist* fillsrc)
{
    int i;
    int rank = odom->rank;
    int firstdim = (index == 0); /* last dimension*/
    int lastdim = (index == (rank - 1)); /* last dimension*/
    size_t count;
    Symbol* basetype = vsym->typ.basetype;
    int isunlimited = (odom->declsize[index] == 0);
    int pushed=0;

    ASSERT(index >= 0 && index < rank);

    count = odom->count[index];

    if(!firstdim && isunlimited && issublist(src)) {
	srcpush(src);
	pushed = 1;
    }
   
    if(lastdim) {
        for(i=0;i<count;i++) {
            f77data_basetype(basetype,src,databuf,fillsrc);
	}
    } else {
        /* now walk count elements and generate recursively */
        for(i=0;i<count;i++) {
	    f77data_array(vsym,databuf,src,odom,index+1,fillsrc);
	}
    }

    if(isunlimited && pushed) srcpop(src);

    return;
}
Esempio n. 7
0
/* Used for compound instances */
static void
genbin_compound(Symbol* tsym, Datasrc* datasrc, Datalist* fillsrc, Bytebuffer* memory)
{
    int i;
    int base = bblength(memory);
    if(!issublist(datasrc)) {
        semerror(srcline(datasrc),"Compound data must be enclosed in {..}");
    }
    /* Use this datasrc list to get values for compound fields */
    srcpush(datasrc);
    for(i=0;i<listlength(tsym->subnodes);i++) {
        Symbol* field = (Symbol*)listget(tsym->subnodes,i);
	if(!srcmore(datasrc)) { /* generate a fill value*/
	    Datalist* fillsrc = getfiller(tsym);
	    genbin_data(field,datasrc,fillsrc,memory);
	} else
	    genbin_data(field,datasrc,NULL,memory);
    }
    srcpop(datasrc);
    /* Re: github issue 323: we may need to pad the end of the structure
       to make its size be a multiple of the largest alignment.
    */
    alignto(tsym->cmpdalignment,buf,base);
}
Esempio n. 8
0
void
gen_chararray(Symbol* vsym,
		Bytebuffer* databuf,
		Datasrc* src,
		Odometer* odom,
		int index)
{
    /* Assume that all dimensions from index+1 to rank-1 are !unlimited */
    int i;
    int rank = odom->rank;
    int lastdim = (index == (rank - 1)); /* last dimension*/
    int firstdim = (index == 0);
    int isunlimited = (odom->declsize[index] == NC_UNLIMITED);
    int exploded = 0;
    Constant* con;

    if(lastdim) {
	gen_chararraysuffix(vsym,databuf,src,odom,index);
	return;
    }

    ASSERT(index >= 0 && index < rank);
    odom->index[index] = odom->start[index]; /* reset */

    if(isunlimited) {
	size_t slicesize;
	Constant* con;
	if(!firstdim) {
	    if(!issublist(src)) {
		semerror(srcline(src),"Unlimited data must be enclosed in {..}");
		return;
	    }
	    srcpush(src); /* enter the unlimited data */
	}
	con=srcpeek(src);
        /* Break up the constant if it is too large */
	slicesize = odomsubarray(odom,index+1);
	if(con != NULL && con->value.stringv.len > slicesize) {
	    /* Constant is larger than just our slice */
	    /* Explode the constant into subchunks */
	    exploded = stringexplode(src,slicesize);
	}
	while((con=srcpeek(src))!=NULL) {
	    gen_chararray(vsym,databuf,src,odom,index+1);
	    odom->index[index]++;
	}
	odom->unlimitedsize[index] = odom->index[index];
	if(exploded) srcpop(src);
	if(!firstdim) srcpop(src);
    } else { /* !isunlimited*/
	size_t slicesize;
	con = srcpeek(src);
	ASSERT(!lastdim);
	/* Break up the constant if it is too large */
	slicesize = odomsubarray(odom,index+1);
	if(con != NULL && con->value.stringv.len > slicesize) {
	    /* Constant is larger than just our slice */
	    /* Explode the constant into subchunks */
	    exploded = stringexplode(src,slicesize);
	}
	for(i=0;i<odom->declsize[index];i++) {
	    gen_chararray(vsym,databuf,src,odom,index+1);
	}
	if(exploded) srcpop(src);
    }
}
Esempio n. 9
0
static void
gen_chararraysuffix(Symbol* vsym,
	      Bytebuffer* databuf,
	      Datasrc* src,
	      Odometer* odom,
	      int index)
{
    int i;
    int rank = odom->rank;
    int lastdim = (index == (rank - 1)); /* last dimension*/
    int firstdim = (index == 0);
    size_t declsize = odom->declsize[index];
    int isunlimited = (declsize==NC_UNLIMITED);
    Constant* con;

    ASSERT(index >= 0 && index < rank);
    odom->index[index] = odom->start[index]; /* reset*/

    con = srcpeek(src);
    if(!isunlimited) {
	if(con != NULL && !isstringable(con->nctype)) {
	    semerror(srcline(src),
		     "Encountered non-string constant in char data: %s",
		     vsym->name);
	    return;
	}
	if(lastdim) {
	    /* To mimic ncgen original, it appears we have to hack.
	       I think firstdim==lastdim may work.
	    */
	    for(i=0;i<declsize;) {
		int slen;
		con = srcnext(src);
		if(con == NULL) break;
		slen = collectstring(con,declsize,databuf);
		if(!firstdim && slen < declsize) slen=fillstring(declsize,slen,databuf);
		i += slen;
	    }
	    if(firstdim && i < declsize) i = fillstring(declsize,i,databuf);
   	    odom->index[index] = i;
	} else { /* ! lastdim*/
	    int exploded = 0;
	    size_t slicesize = odometertotal(odom,index+1);
	    if(con != NULL && con->nctype == NC_STRING
               && con->value.stringv.len > slicesize) {
		/* Constant is larger than just our slice */
		/* Explode the constant into subchunks */
		exploded = stringexplode(src,slicesize);
	    }
	    for(i=0;i<odom->declsize[index];i++) {
		gen_chararraysuffix(vsym,databuf,src,odom,index+1);
		odom->index[index]++;
	    }
	    if(exploded) srcpop(src);
	}
    } else { /* unlimited => lastdim*/
	Constant* con;
	if(!firstdim) {
	    if(!issublist(src)) {
		semerror(srcline(src),"Unlimited data must be enclosed in {..}");
		return;
	    }
	    srcpush(src); /* enter the unlimited data */
	}
	/* Basically, collect all the strings until we run out */
	i = 0;
	while((con=srcnext(src))!=NULL) {
	    i += collectstring(con,0,databuf);
	}
	odom->index[index] = i;
	odom->unlimitedsize[index] = odom->index[index];
	if(!firstdim) srcpop(src);
    }
}
Esempio n. 10
0
/* Generate an instance of the basetype using datasrc */
void
cdata_basetype(Symbol* tsym, Datasrc* datasrc, Bytebuffer* codebuf, Datalist* fillsrc)
{
    int usecmpd;

    switch (tsym->subclass) {

    case NC_ENUM:
    case NC_OPAQUE:
    case NC_PRIM:
	if(issublist(datasrc)) {
	    semerror(srcline(datasrc),"Expected primitive found {..}");
	}
	bbAppend(codebuf,' ');
	cdata_primdata(tsym,datasrc,codebuf,fillsrc);
	break;

    case NC_COMPOUND: {
	int i;
        Constant* con;
	if(!isfillvalue(datasrc) && !issublist(datasrc)) {/* fail on no compound*/
	    semerror(srcline(datasrc),"Compound data must be enclosed in {..}");
        }
        con = srcnext(datasrc);
	if(con->nctype == NC_FILLVALUE) {
	    Datalist* filler = getfiller(tsym,fillsrc);
	    ASSERT(filler->length == 1);
	    con = &filler->data[0];
	    if(con->nctype != NC_COMPOUND) {
	        semerror(con->lineno,"Compound data fill value is not enclosed in {..}");
	    }
	}
        srcpushlist(datasrc,con->value.compoundv); /* enter the sublist*/
        bbAppend(codebuf,'{');
        for(i=0;i<listlength(tsym->subnodes);i++) {
            Symbol* field = (Symbol*)listget(tsym->subnodes,i);
            bbAppend(codebuf,' ');
            cdata_basetype(field,datasrc,codebuf,NULL);
	}
        bbAppend(codebuf,'}');
        srcpop(datasrc);
	} break;

    case NC_VLEN: {
        Constant* con;
	if(!isfillvalue(datasrc) && !issublist(datasrc)) {/* fail on no compound*/
	    semerror(con->lineno,"Vlen data must be enclosed in {..}");
        }
        con = srcnext(datasrc);
	if(con->nctype == NC_FILLVALUE) {
	    Datalist* filler = getfiller(tsym,fillsrc);
	    ASSERT(filler->length == 1);
	    con = &filler->data[0];
	    if(con->nctype != NC_COMPOUND) {
	        semerror(con->lineno,"Vlen data fill value is not enclosed in {..}");
	    }
	}
        /* generate the nc_vlen_t instance*/
        bbprintf0(stmt,"{%u (void*)vlen_%u}",
	         con->value.compoundv->vlen.count,
    		 con->value.compoundv->vlen.uid);
        bbCatbuf(codebuf,stmt);
        } break;

    case NC_FIELD:
	/* enclose in braces if and only if field is an array */
	usecmpd = (issublist(datasrc) && tsym->typ.dimset.ndims > 0);
	if(usecmpd) srcpush(datasrc);
	if(tsym->typ.dimset.ndims > 0) {
	    Odometer* fullodom = newodometer(&tsym->typ.dimset,NULL,NULL);
            cdata_fieldarray(tsym->typ.basetype,datasrc,fullodom,0,codebuf);
	    odometerfree(fullodom);
	} else {
	    cdata_basetype(tsym->typ.basetype,datasrc,codebuf,NULL);
	}
	if(usecmpd) srcpop(datasrc);
	break;

    default: PANIC1("cdata_basetype: unexpected subclass %d",tsym->subclass);
    }
}