コード例 #1
0
ファイル: genchar.c プロジェクト: Federico2014/edg4x-rose
int
collectstring(Constant* con, size_t declsize, Bytebuffer* databuf)
{
    int i = 0;
    if(con != NULL) {
	ASSERT(isstringable(con->nctype));
        if(con->nctype == NC_STRING) {
            if(declsize > 0 && con->value.stringv.len >= (declsize-i)) {
                bbAppendn(databuf,con->value.stringv.stringv,con->value.stringv.len);
                i = declsize;
            } else if(con->value.stringv.len == 0) {
                i = 0;
            } else {
                /* Append */
                bbCat(databuf,con->value.stringv.stringv);
                i = con->value.stringv.len;
	    }
	} else if(con->nctype == NC_FILLVALUE) {
            bbAppend(databuf,NC_FILL_CHAR);
	    i = 1;
        } else {
            /* Append */
            bbAppend(databuf,con->value.charv);
            i = 1;
	}                   
    }
    return i;
}
コード例 #2
0
ファイル: genchar.c プロジェクト: Federico2014/edg4x-rose
void
gen_charfield(Datasrc* src, Odometer* odom, int index, Bytebuffer* fieldbuf)
{
    int i;
    int lastdim = (index == (odom->rank - 1));
    size_t declsize = odom->declsize[index];
    Constant* con;

    ASSERT(declsize != 0);

    if(lastdim) {
	for(i=0;i<declsize;) {
	    con = srcnext(src);
	    if(con == NULL) break;
	    if(!isstringable(con->nctype)) {
	        semerror(srcline(src),
	     		"Encountered non-string constant in compound field");
		return;
	    }
	    i += collectstring(con,declsize,fieldbuf);
	}
        if(i < declsize) i=fillstring(declsize,i,fieldbuf);
    } else { /* ! lastdim*/
	int exploded = 0;
	size_t slicesize;
	/* Compute subslice size */
        slicesize = 1;
	for(i=index+1;i<odom->rank;i++)
	    slicesize *= MAX(odom->declsize[i],odom->unlimitedsize[i]);
	con = srcpeek(src);
	if(con != NULL && !isstringable(con->nctype)) {
	    semerror(srcline(src),
	     		"Encountered non-string constant in compound field");
	    return;
	}
	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<declsize;i++) {
	    gen_charfield(src,odom,index+1,fieldbuf);
	}
	if(exploded) srcpop(src);
    }
}
コード例 #3
0
ファイル: genchar.c プロジェクト: UV-CDAT/netcdf-c
/* Recursive helper */
static void
gen_chararrayr(Dimset* dimset, int dimindex,
               Bytebuffer* databuf, Datalist* data, int fillchar,
	       int unitsize, int expectedsize)
{
    int i;
    size_t dimsize = declsizefor(dimset,dimindex);
    int rank = dimset->ndims;
    int firstunlim = findunlimited(dimset,0);
    int lastunlimited = findlastunlimited(dimset);
    int nextunlimited = findunlimited(dimset,dimindex+1);
    int islastgroup = (lastunlimited == rank || dimindex >= lastunlimited || dimindex == rank-1);
    Odometer* subodom = NULL;

    ASSERT(rank > 0);
    ASSERT((islastgroup));

    /* we should be at a list of simple constants */
    for(i=0;i<data->length;i++) {
        NCConstant* c = datalistith(data,i);
        ASSERT(!islistconst(c));
        if(isstringable(c->nctype)) {
            int j;
            size_t constsize;
            constsize = gen_charconstant(c,databuf,fillchar);
            if(constsize % unitsize > 0) {
                size_t padsize = unitsize - (constsize % unitsize);
                for(j=0;j<padsize;j++) bbAppend(databuf,fillchar);
            }
        } else {
            semwarn(constline(c),
                   "Encountered non-string and non-char constant in datalist; ignored");
        }
    }/* for */

    /* If |databuf| > expectedsize, complain: exception is zero length */
    if(bbLength(databuf) == 0 && expectedsize == 1) {
        /* this is okay */
    } else if(bbLength(databuf) > expectedsize) {
        semwarn(data->data[0].lineno,"character data list too long; expected %d character constant, found %d: ",expectedsize,bbLength(databuf));
    } else {
        size_t bufsize = bbLength(databuf);
        /* Pad to size dimproduct size */
        if(bufsize % expectedsize > 0) {
            size_t padsize = expectedsize - (bufsize % expectedsize);
            for(i=0;i<padsize;i++) bbAppend(databuf,fillchar);
        }
    }
}
コード例 #4
0
ファイル: genchar.c プロジェクト: aloliveira2323/netcdf-c
/* Recursive helper */
static void
gen_chararrayr(Dimset* dimset, int dimindex, int lastunlimited,
               Bytebuffer* databuf, Datalist* data, int fillchar,
	       int unitsize, int expectedsize)
{
    int i;
    size_t dimsize = dimset->dimsyms[dimindex]->dim.declsize;

    if(dimindex < lastunlimited) {
	/* keep recursing */
        for(i=0;i<dimsize;i++) {
	    NCConstant* c = datalistith(data,i);
	    ASSERT(islistconst(c));
	    gen_chararrayr(dimset,dimindex+1,lastunlimited,databuf,
			   c->value.compoundv,fillchar,unitsize,expectedsize);
	}
    } else {/* we should be at a list of simple constants */
	for(i=0;i<data->length;i++) {
	    NCConstant* c = datalistith(data,i);
	    ASSERT(!islistconst(c));
	    if(isstringable(c->nctype)) {
		int j;
	        size_t constsize;
	        constsize = gen_charconstant(c,databuf,fillchar);
		if(constsize % unitsize > 0) {
	            size_t padsize = unitsize - (constsize % unitsize);
	            for(j=0;j<padsize;j++) bbAppend(databuf,fillchar);
		}
	    } else {
	        semwarn(constline(c),
		       "Encountered non-string and non-char constant in datalist; ignored");
	    }
	}
    }
    /* If |databuf| > expectedsize, complain: exception is zero length */
    if(bbLength(databuf) == 0 && expectedsize == 1) {
	/* this is okay */
    } else if(bbLength(databuf) > expectedsize) {
	semwarn(data->data[0].lineno,"character data list too long");
    } else {
	size_t bufsize = bbLength(databuf);
	/* Pad to size dimproduct size */
	if(bufsize % expectedsize > 0) {
	    size_t padsize = expectedsize - (bufsize % expectedsize);
            for(i=0;i<padsize;i++) bbAppend(databuf,fillchar);
	}
    }
}
コード例 #5
0
ファイル: genchar.c プロジェクト: UV-CDAT/netcdf-c
void
gen_charvlen(Datalist* data, Bytebuffer* databuf)
{
    int i;
    NCConstant* c;

    ASSERT(bbLength(databuf) == 0);

    for(i=0;i<data->length;i++) {
        c = datalistith(data,i);
        if(isstringable(c->nctype)) {
            (void)gen_charconstant(c,databuf,NC_FILL_CHAR);
        } else {
            semerror(constline(c),
                     "Encountered non-string and non-char constant in datalist");
            return;
        }
    }
}
コード例 #6
0
ファイル: genchar.c プロジェクト: Federico2014/edg4x-rose
void
gen_charvlen(Datasrc* vlensrc, Bytebuffer* databuf)
{
    int count;
    Bytebuffer* vlenbuf = bbNew();
    Constant* con;

    count = 0;
    while((con=srcnext(vlensrc)) != NULL) {
	if(!isstringable(con->nctype)) {
	    semerror(srcline(vlensrc),
		     "Encountered non-string constant in vlen constant");
	    goto done;
        }
	count += collectstring(con,0,vlenbuf);
    }

done:
    bbFree(vlenbuf);
}
コード例 #7
0
ファイル: genchar.c プロジェクト: UV-CDAT/netcdf-c
static void
gen_leafchararray(Dimset* dimset, int dimindex, Datalist* data,
                   Bytebuffer* charbuf, int fillchar)
{
    int i;
    size_t expectedsize,xproduct,unitsize;
    int rank = rankfor(dimset);

    ASSERT(bbLength(charbuf) == 0);
    ASSERT((findlastunlimited(dimset) == rank
            || findlastunlimited(dimset) == dimindex));

    /*
    There are a number of special cases that must be
    considered, mostly driven by the need to keep consistent
    with ncgen3.  These cases are driven by the number of
    dimensions, which dimensions are unlimited (if any), etc.

    The general rule is based on the size of the last
    dimension, we compute the required size (after padding)
    of each string constant. Expected size is then the size
    of concat of the string constants after padding.

    There is another special case used for back compatability with ncgen3.
    In the datalist, all sequences of character constants (i.e. 'X')
    are concatenated into a single string; the result, however is not
    concatenated with any trailing or leading string (with double quotes).
    */

    /* Rebuild the datalist to merge 'x' constants */
    {
	int i,cccount = 0;
	/* Do initial walk */
	for(i=0;i<datalistlen(data);i++) {
	    NCConstant* con = datalistith(data,i);
	    if(consttype(con) == NC_CHAR || consttype(con) == NC_BYTE) {
		cccount++;
	    }
	}
	if(cccount > 1) {
	    char* accum = (char*)malloc(cccount+1);
	    int len = 0;
	    Datalist* newlist = builddatalist(datalistlen(data));
	    int lineno = 0;
            NCConstant* con;
	    for(i=0;i<datalistlen(data);i++) {
	        con = datalistith(data,i);
	        if(consttype(con) == NC_CHAR || consttype(con) == NC_BYTE) {
		    if(len == 0)
			lineno = constline(con);
		    accum[len] = con->value.charv;
		    len++;
		} else {
		    if(len > 0) {
			con = makeconst(lineno,len,accum);
			len = 0;
			lineno = 0;
		    }
		    dlappend(newlist,con);
		}
	    }
	    /* deal with any unclosed strings */
	    if(len > 0) {
		con = makeconst(lineno,len,accum);
		len = 0;
		lineno = 0;
	        dlappend(newlist,con);
	    }
	    free(accum);
	    data = newlist;
	}
    }

    /* Compute crossproduct upto (but not includng) the last dimension */
    xproduct = crossproduct(dimset,dimindex,rank-1);

    /* Start casing it out */
    if(rank == 0) {
        unitsize = 1;
        expectedsize = (xproduct * unitsize);
    } else if(rank == 1) {
	unitsize = 1;
        expectedsize = (xproduct * declsizefor(dimset,rank-1));
    } else if(isunlimited(dimset,rank-1)) {/* last dimension is unlimited */
        unitsize = 1;
        expectedsize = (xproduct*declsizefor(dimset,rank-1));
    } else { /* rank > 0 && last dim is not unlimited */
	unitsize =  declsizefor(dimset,rank-1);
        expectedsize = (xproduct * unitsize);
    }

    for(i=0;i<data->length;i++) {
        NCConstant* c = datalistith(data,i);
        ASSERT(!islistconst(c));
        if(isstringable(c->nctype)) {
            int j;
            size_t constsize;
            constsize = gen_charconstant(c,charbuf,fillchar);
            if(constsize == 0 || constsize % unitsize > 0) {
                size_t padsize = unitsize - (constsize % unitsize);
                for(j=0;j<padsize;j++) bbAppend(charbuf,fillchar);
            }
        } else {
            semwarn(constline(c),"Encountered non-string and non-char constant in datalist; ignored");
        }
    }
    /* If |databuf| > expectedsize, complain: exception is zero length */
    if(bbLength(charbuf) == 0 && expectedsize == 1) {
        /* this is okay */
    } else if(bbLength(charbuf) > expectedsize) {
        semwarn(data->data[0].lineno,"character data list too long; expected %d character constant, found %d: ",expectedsize,bbLength(charbuf));
    } else {
        size_t bufsize = bbLength(charbuf);
        /* Pad to size dimproduct size */
        if(bufsize % expectedsize > 0) {
            size_t padsize = expectedsize - (bufsize % expectedsize);
            for(i=0;i<padsize;i++) bbAppend(charbuf,fillchar);
        }
    }
}
コード例 #8
0
ファイル: genchar.c プロジェクト: aloliveira2323/netcdf-c
void
gen_leafchararray(Dimset* dimset, int lastunlim, Datalist* data,
                   Bytebuffer* databuf, Datalist* fillsrc)
{
    int i;
    size_t expectedsize,xproduct,unitsize;
    int ndims = dimset->ndims;
    int fillchar = getfillchar(fillsrc);

    ASSERT(bbLength(databuf) == 0);

    /* Assume dimindex is the last unlimited (or 0 if their are
       no unlimiteds => we should be at a list of simple constants
    */

    /* Compute crossproduct upto the last dimension,
       starting at the last unlimited
    */
    xproduct = crossproduct(dimset,lastunlim,ndims-1);

    /* Compute the required size (after padding) of each string constant */
    /* expected size is the size of concat of the string constants
       after padding
    */
    if(ndims == 0) {
	unitsize = 1;
        expectedsize = (xproduct * unitsize);
    } else
    if(lastunlim == ndims-1) {/* last dimension is unlimited */
        unitsize = 1;
        expectedsize = (xproduct*dimset->dimsyms[lastunlim]->dim.declsize);
    } else
    { /* last dim is not unlimited */
        unitsize = dimset->dimsyms[ndims-1]->dim.declsize;
        expectedsize = (xproduct * unitsize);
    }

    for(i=0;i<data->length;i++) {
	NCConstant* c = datalistith(data,i);
	ASSERT(!islistconst(c));
	if(isstringable(c->nctype)) {
	    int j;
	    size_t constsize;
	    constsize = gen_charconstant(c,databuf,fillchar);
	    if(constsize == 0 || constsize % unitsize > 0) {
	        size_t padsize = unitsize - (constsize % unitsize);
	        for(j=0;j<padsize;j++) bbAppend(databuf,fillchar);
	    }
	} else {
	    semwarn(constline(c),"Encountered non-string and non-char constant in datalist; ignored");
	}
    }
    /* If |databuf| > expectedsize, complain: exception is zero length */
    if(bbLength(databuf) == 0 && expectedsize == 1) {
	/* this is okay */
    } else if(bbLength(databuf) > expectedsize) {
	semwarn(data->data[0].lineno,"character data list too long");
    } else {
	size_t bufsize = bbLength(databuf);
	/* Pad to size dimproduct size */
	if(bufsize % expectedsize > 0) {
	    size_t padsize = expectedsize - (bufsize % expectedsize);
            for(i=0;i<padsize;i++) bbAppend(databuf,fillchar);
	}
    }
}
コード例 #9
0
ファイル: genchar.c プロジェクト: Federico2014/edg4x-rose
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);
    }
}