Пример #1
0
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
void
gen_charattr(Symbol* asym, Bytebuffer* databuf)
{
    Datasrc* src;
    Constant* con;

    if(asym->data == NULL) return;
    src = datalist2src(asym->data);
    while((con=srcnext(src))) {
	switch (con->nctype) {
	/* Following list should be consistent with isstringable */
	case NC_CHAR:
	    bbAppend(databuf,con->value.charv);
	    break;
	case NC_BYTE:
	    bbAppend(databuf,con->value.int8v);
	    break;
	case NC_UBYTE:
	    bbAppend(databuf,con->value.uint8v);
	    break;
	case NC_STRING:
	    bbCat(databuf,con->value.stringv.stringv);
	    bbNull(databuf);
	    break;
	case NC_FILL:
	    bbAppend(databuf,NC_FILL_CHAR);
	    break;
	default:
	    semerror(srcline(src),
		     "Encountered non-string constant in attribute: %s",
		     asym->name);
	    return;
	}
    }
}
Пример #3
0
static size_t
gen_charconstant(NCConstant* con, Bytebuffer* databuf, int fillchar)
{
    /* Following cases should be consistent with isstringable */
    size_t constsize = 1;
    switch (con->nctype) {
    case NC_CHAR:
        bbAppend(databuf,con->value.charv);
        break;
    case NC_BYTE:
        bbAppend(databuf,con->value.int8v);
        break;
    case NC_UBYTE:
        bbAppend(databuf,con->value.uint8v);
        break;
    case NC_STRING:
        constsize = con->value.stringv.len;
        bbAppendn(databuf,con->value.stringv.stringv,
                         con->value.stringv.len);
        bbNull(databuf);
        break;
    case NC_FILL:
        bbAppend(databuf,fillchar);
        break;
    default:
        PANIC("unexpected constant type");
    }
    return constsize;
}
Пример #4
0
/* Requires that the string be balanced
   WRT to braces
*/
static char*
commifyr(char* p, Bytebuffer* buf)
{
    int comma = 0;
    int c;
    while((c=*p++)) {
	if(c == ' ') continue;
	if(c == ',') continue;
	else if(c == '}') {
	    break;
	}
	if(comma) bbCat(buf,", "); else comma=1;
	if(c == '{') {
	    bbAppend(buf,'{');
	    p = commifyr(p,buf);
	    bbAppend(buf,'}');
	} else if(c == '\'' || c == '\"') {
	    p = wordstring(p,buf,c);
	} else {
	    bbAppend(buf,c);
	    p=word(p,buf);
	}
    }
    return p;
}
Пример #5
0
void
cquotestring(Bytebuffer* databuf, char quote)
{
    char* escaped = escapify(bbContents(databuf),'"',bbLength(databuf));
    bbClear(databuf);
    bbAppend(databuf,quote);
    bbCat(databuf,escaped);
    bbAppend(databuf,quote);
}
Пример #6
0
static void
jescapifychar(UTF16 c, int quote, Bytebuffer* s)
{
    /* Separate out ascii from UTF16 */
    if(c <= '\177') {
	/* Separate printables from controls */
        if(c >= ' ' && c < '\177') {
	    if (c == quote) {
		bbAppend(s,'\\');
	    }
	    bbAppend(s,(char)c);
	} else switch (c) {
	    case '\t': bbCat(s,"\\t"); break;
	    case '\b': bbCat(s,"\\b"); break;
	    case '\n': bbCat(s,"\\n"); break;
	    case '\r': bbCat(s,"\\r"); break;
	    case '\f': bbCat(s,"\\f"); break;
	    default:
		{ /* Do hex escape */
		int hex1 = (c & 0x0f);
		int hex2 = ((c >> 4) & 0x0f);
		int hex3 = ((c >> 8) & 0x0f);
		int hex4 = ((c >> 12) & 0x0f);
		bbAppend(s,'\\');
		bbAppend(s,'u');
		bbAppend(s,hexdigits[hex4]);
		bbAppend(s,hexdigits[hex3]);
		bbAppend(s,hexdigits[hex2]);
		bbAppend(s,hexdigits[hex1]);
		} break;
	}
    } else { /* Do \uxxxx escapes */
Пример #7
0
/* 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);
        }
    }
}
Пример #8
0
/* 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);
	}
    }
}
Пример #9
0
static void
f77data_primdata(Symbol* basetype, Datasrc* src, Bytebuffer* codebuf, Datalist* fillsrc)
{
    Constant* prim;
    Constant target;

    prim = srcnext(src);
    if(prim == NULL) prim = &fillconstant;

    ASSERT(prim->nctype != NC_COMPOUND);

    if(prim->nctype == NC_FILLVALUE) {
	Datalist* filler = getfiller(basetype,fillsrc);
	ASSERT(filler->length == 1);
	srcpushlist(src,filler);
	bbAppend(codebuf,' ');
        f77data_primdata(basetype,src,codebuf,NULL);
	srcpop(src);
	goto done;
    }

    target.nctype = basetype->typ.typecode;

    convert1(prim,&target);
    bbCat(codebuf,f77data_const(&target));
    
done:
    return;
}
Пример #10
0
/* Used only for structure field arrays*/
static void
cdata_fieldarray(Symbol* basetype, Datasrc* src, Odometer* odom, int index,
		Bytebuffer* codebuf)
{
    int i;
    int rank = odom->rank;
    unsigned int size = odom->declsize[index];
    int lastdim = (index == (rank - 1)); /* last dimension*/
    int chartype = (basetype->typ.typecode == NC_CHAR);

    if(chartype) {
	/* Collect the char field in a separate buffer */
	Bytebuffer* fieldbuf = bbNew();
        gen_charfield(src,odom,index,fieldbuf);
	/* Add to the existing data buf as a single constant */
	cquotestring(fieldbuf);
	bbCat(codebuf," ");
        bbCatbuf(codebuf,fieldbuf);
	bbFree(fieldbuf);
    } else {
        ASSERT(size != 0);
        for(i=0;i<size;i++) {
            if(lastdim) {
	        bbAppend(codebuf,' ');
	        cdata_basetype(basetype,src,codebuf,NULL);
            } else { /* !lastdim*/
	        cdata_fieldarray(basetype,src,odom,index+1,codebuf);
	    }
	}
    }
}
Пример #11
0
/* Add invisible NULL terminator */
int
bbNull(Bytebuffer* bb)
{
    bbAppend(bb,'\0');
    bb->length--;
    return 1;
}
Пример #12
0
char*
word(char* p, Bytebuffer* buf)
{
    int c;
    while((c=*p++)) {
	if(c == '}' || c == ' ' || c == ',') break;
	if(c == '\\') {
	    bbAppend(buf,c);
	    c=*p++;
	    if(!c) break;
	}
	bbAppend(buf,(char)c);
    }
    p--; /* leave terminator for parent */
    return p;
}
Пример #13
0
/* Fill */
static int
fillstring(size_t declsize, int len, Bytebuffer* databuf)
{
    for(;len<declsize;len++)
        bbAppend(databuf,NC_FILL_CHAR);
    return len;
}
Пример #14
0
static char*
wordstring(char* p, Bytebuffer* buf, int quote)
{
    int c;
    bbAppend(buf,quote);
    while((c=*p++)) {
	if(c == '\\') {
	    bbAppend(buf,c);
	    c = *p++;
	    if(c == '\0') return --p;
	} else if(c == quote) {
	    bbAppend(buf,c);
	    return p;
	}
	bbAppend(buf,c);
    }
    return p;
}
Пример #15
0
static void
vbbprintf(Bytebuffer* buf, const char* fmt, va_list argv)
{
    char tmp[128];
    const char* p;
    int c;
    int hcount;
    int lcount;

    char* text;

    for(p=fmt;(c=*p++);) {
	hcount = 0; lcount = 0;
	switch (c) {
	case '%':
retry:	    switch ((c=*p++)) {
	    case '\0': bbAppend(buf,'%'); p--; break;
	    case '%': bbAppend(buf,c); break;
	    case 'h':
		hcount++;
		while((c=*p) && (c == 'h')) {hcount++; p++;}
		if(hcount > 2) hcount = 2;
		goto retry;
	    case 'l':
		lcount++;
		while((c=*p) && (c == 'l')) {
		    lcount++;
		    p++;
		}
		if(lcount > 2) lcount = 2;
		goto retry;
	    case 'u':
		if(hcount == 2) {
   	            snprintf(tmp,sizeof(tmp),"%hhu",
			(unsigned int)va_arg(argv,unsigned int));
		} else if(hcount == 1) {
   	            snprintf(tmp,sizeof(tmp),"%hu",
			(unsigned int)va_arg(argv,unsigned int));
		} else if(lcount == 2) {
Пример #16
0
static void
cdata_primdata(Symbol* basetype, Datasrc* src, Bytebuffer* codebuf, Datalist* fillsrc)
{
    Constant* prim;
    Constant target;

    prim = srcnext(src);
    if(prim == NULL) prim = &fillconstant;

    ASSERT(prim->nctype != NC_COMPOUND);

    if(prim->nctype == NC_FILLVALUE) {
	Datalist* filler = getfiller(basetype,fillsrc);
	ASSERT(filler->length == 1);
	srcpushlist(src,filler);
	bbAppend(codebuf,' ');
        cdata_primdata(basetype,src,codebuf,NULL);
	srcpop(src);
	goto done;
    }

    target.nctype = basetype->typ.typecode;

    if(target.nctype != NC_ECONST) {
	convert1(prim,&target);
    }

    switch (target.nctype) {
    case NC_ECONST:
        if(basetype->subclass != NC_ENUM) {
	    semerror(prim->lineno,"Conversion to enum not supported (yet)");
	} else {
	    Datalist* econ = builddatalist(1);
	    Symbol* enumv = prim->value.enumv;
	    srcpushlist(src,econ);
	    dlappend(econ,&enumv->typ.econst);
	    cdata_primdata(enumv->typ.basetype,src,codebuf,fillsrc);
	    srcpop(src);
	 } break;
     case NC_OPAQUE: {
	    setprimlength(&target,basetype->typ.size*2);
	} break;
    default: break;
    }
    bbCat(codebuf,cdata_const(&target));
    
done:
    return;
}
Пример #17
0
static int
c_listend(Generator* generator, ListClass lc, int uid, size_t count, Bytebuffer* buf, ...)
{
    switch (lc) {
    case LISTCOMPOUND:
    case LISTFIELDARRAY:
	bbAppend(buf,'}');
	break;
    case LISTDATA:
    case LISTVLEN:
    case LISTATTR:
	break;
    }
    return 1;
}
Пример #18
0
static int
c_listbegin(Generator* generator, ListClass lc, size_t size, Bytebuffer* codebuf, int* uidp, ...)
{
    if(uidp) *uidp = ++c_uid;
    switch (lc) {
    case LISTVLEN:
    case LISTATTR:
    case LISTDATA:
	break;
    case LISTFIELDARRAY:
    case LISTCOMPOUND:
        bbAppend(codebuf,'{');
	break;
    }
    return 1;
}
Пример #19
0
static int
c_list(Generator* generator, ListClass lc, int uid, size_t count, Bytebuffer* codebuf, ...)
{
    switch (lc) {
    case LISTVLEN:
    case LISTATTR:
        if(count > 0) bbCat(codebuf,", ");
	break;
    case LISTDATA:
    case LISTCOMPOUND:
    case LISTFIELDARRAY:
        bbAppend(codebuf,' ');
	break;
    }
    return 1;
}
Пример #20
0
/* Generate an instance of the basetype using datasrc */
void
f77data_basetype(Symbol* tsym, Datasrc* datasrc, Bytebuffer* codebuf, Datalist* fillsrc)
{
    switch (tsym->subclass) {

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

    default: PANIC1("f77data_basetype: unexpected subclass %d",tsym->subclass);
    }
}
Пример #21
0
/* Specialty wrappers for f77data_data */
void
f77data_attrdata(Symbol* asym, Bytebuffer* databuf)
{
    Datasrc* src;
    int typecode = asym->typ.basetype->typ.typecode;

    if(asym->data == NULL) return;
    if(typecode == NC_CHAR) {
        gen_charattr(asym,databuf);
    } else {
        src = datalist2src(asym->data);
        while(srcmore(src)) {
	    bbAppend(databuf,' ');
            f77data_basetype(asym->typ.basetype,src,databuf,NULL);
	}
    }
}
Пример #22
0
/*
This walk of the data lists collects
vlen sublists and constructs separate C constants
for each of them. The "id" of each list is then
recorded in the containing datalist.
*/
void
cdata_vlenconstants(List* vlenconstants, Bytebuffer* codebuf)
{
    int i,nvlen;
    Datasrc* vlensrc;
    Bytebuffer* tmp = bbNew();

    nvlen = listlength(vlenconstants);
    for(i=0;i<nvlen;i++) {
	Constant* cmpd = (Constant*)listget(vlenconstants,i);
	int chartype;
	Symbol* tsym = cmpd->value.compoundv->vlen.schema;
        ASSERT(tsym != NULL);
        chartype = (tsym->typ.basetype->typ.typecode == NC_CHAR);

        bbprintf0(tmp,"static const %s vlen_%u[] = ",
	        ctypename(tsym->typ.basetype),
                cmpd->value.compoundv->vlen.uid);
	bbCatbuf(codebuf,tmp);
	vlensrc = datalist2src(cmpd->value.compoundv);
	bbAppend(codebuf,'{');
	if(chartype) {
   	    /* Collect the char vlen in a separate buffer */
	    Bytebuffer* vlenbuf = bbNew();
            gen_charvlen(vlensrc,vlenbuf);
	    /* Add to the existing data buf as a single constant */
   	    cquotestring(vlenbuf);
            bbCatbuf(codebuf,vlenbuf);
   	    bbFree(vlenbuf);
	} else {
	    size_t count = 0;
  	    while(srcmore(vlensrc)) {
	        if(count > 0) bbCat(codebuf,", ");
                cdata_basetype(tsym->typ.basetype,vlensrc,codebuf,NULL);
		count++;
	    }
	    ASSERT(count == cmpd->value.compoundv->vlen.count);
        }
	bbCat(codebuf,"} ;\n");
    }
    bbFree(tmp);
}
Пример #23
0
static void
xescapifychar(unsigned int c, int quote, Bytebuffer* s)
{
    if(c >= ' ' && c < '\177') {
	char* p;
	char** q;
	for(p=printescapable,q=printescape;*p;p++,q++) {if(c==*p) break;}
	if(*p) {
	    bbAppend(s,'&');
	    bbCat(s,*q);
	    bbAppend(s,';');
	} else
	    bbAppend(s,(char)c);
    } else {
	/* Do hex escape */
	    unsigned int hex1 = (c & 0x0f);
	    unsigned int hex2 = ((c >> 4) & 0x0f);
	    bbCat(s,"&#");
	    bbAppend(s,hexdigits[hex2]);
	    bbAppend(s,hexdigits[hex1]);
	    bbAppend(s,';');
    }
}
Пример #24
0
static void
genjstd_primattribute(Symbol* asym, Bytebuffer* code, unsigned long len)
{
    Symbol* basetype = asym->typ.basetype;
    nc_type typecode = basetype->typ.typecode;

    /* Handle NC_CHAR specially */
    if(typecode == NC_CHAR) {
        /* revise the length count */
        len = bbLength(code);
        if(len == 0) {bbAppend(code,'\0'); len++;}
        jquotestring(code,'"');
    } else {
        /* Convert to constant */
        char* code2 = bbDup(code);
        bbClear(code);
        nprintf(stmt,sizeof(stmt),"new %s[]",
                jarraytype(typecode));
        bbCat(code,stmt);
        bbCat(code,"{");
        bbCat(code,code2);
        bbCat(code,"}");
        efree(code2);
    }
    switch (typecode) {
    case NC_BYTE:
    case NC_SHORT:
    case NC_INT:
    case NC_FLOAT:
    case NC_DOUBLE:
	jlined(1,"{");
	nprintf(stmt,sizeof(stmt),"%sArray data = Array.factory(%s.class, new int[]{%lu}, ",
		indented(1),
		jtype(basetype->typ.typecode),
		len);
	jpartial(stmt);
        jprint(code);
	jline(");");
	if(asym->att.var == NULL) {
            nprintf(stmt,sizeof(stmt),"ncfile.addGlobalAttribute(\"%s\",data);",
                jescapifyname(asym->name));
	} else {
            nprintf(stmt,sizeof(stmt),"ncfile.addVariableAttribute(\"%s\",\"%s\",data);",
		jescapifyname(asym->att.var->name),
                jescapifyname(asym->name));
	}
        jlined(1,stmt);
	jlined(1,"}");
        jflush();
        break;

    case NC_CHAR:
	if(asym->att.var == NULL) {
            nprintf(stmt,sizeof(stmt),"ncfile.addGlobalAttribute(\"%s\",%s);",
                jescapifyname(asym->name),
		bbContents(code));
	} else {
            nprintf(stmt,sizeof(stmt),"ncfile.addVariableAttribute(\"%s\",\"%s\",%s);",
		jescapifyname(asym->att.var->name),
                jescapifyname(asym->name),
		bbContents(code));
	}
        jlined(1,stmt);
        jflush();
        break;

    default: break;
    }
}
Пример #25
0
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);
        }
    }
}
Пример #26
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);
    }
}
Пример #27
0
static void
genj_writeattr(Generator* generator, Symbol* asym, Bytebuffer* code,
               int rank, size_t* start, size_t* count)
{
    Symbol* basetype = asym->typ.basetype;
    nc_type typecode = basetype->typ.typecode;
    /* default assumption */
    size_t len = asym->data == NULL?0:asym->data->length; 

    codeprintf("%s/* attribute: %s */\n",indented(1),asym->name);

    /* Handle NC_CHAR specially */
    if(typecode == NC_CHAR) {
        /* revise the length count */
        len = bbLength(code);
        if(len == 0) {
	    bbAppend(code,'\0'); len++;
	    bbClear(code);
	    bbCat(code,"\"\"");
	    len++;
	} else
            jquotestring(code,'"');
	bbNull(code);
    } else { /* not NC_CHAR*/
        char* code2;
	commify(code);
        /* Convert to constant */
        code2 = bbDup(code);
        bbClear(code);
        bbprintf0(stmt,"new %s[]",
                jarraytype(typecode));
        bbCatbuf(code,stmt);
        bbCat(code,"{");
        bbCat(code,code2);
        bbCat(code,"}");
        efree(code2);
    }
    switch (typecode) {
    case NC_BYTE:
    case NC_SHORT:
    case NC_INT:
    case NC_FLOAT:
    case NC_DOUBLE:
	codelined(1,"{");
	bbprintf0(stmt,"%sArray data = Array.factory(%s.class, new int[]{%lu}, ",
		indented(1),
		jtype(basetype->typ.typecode),
		len);
	codedump(stmt);
        codedump(code);
	codeline(");");
	if(asym->att.var == NULL) {
            bbprintf0(stmt,"%sncfile.addGlobalAttribute(\"%s\",data);\n",
                indented(1),jescapifyname(asym->name));
	} else {
            bbprintf0(stmt,"%sncfile.addVariableAttribute(\"%s\",\"%s\",data);\n",
		indented(1),
		jescapifyname(asym->att.var->name),
                jescapifyname(asym->name));
	}
        codedump(stmt);
	codelined(1,"}");
        codeflush();
        break;

    case NC_CHAR:
	if(asym->att.var == NULL) {
            bbprintf0(stmt,"%sncfile.addGlobalAttribute(\"%s\",%s);\n",
		indented(1),
                jescapifyname(asym->name),
		bbContents(code));
	} else {
            bbprintf0(stmt,"%sncfile.addVariableAttribute(\"%s\",\"%s\",%s);\n",
		indented(1),
		jescapifyname(asym->att.var->name),
                jescapifyname(asym->name),
		bbContents(code));
	}
        codedump(stmt);
        codeflush();
        break;

    default: break;
    }
    codeflush();
}
Пример #28
0
void
expand_escapes(
     Bytebuffer *s, /* fill with contents of yytext, with escapes expanded */
     char *yytext,
     int yyleng)
{
    char *t, *endp;
    yytext[yyleng-1]='\0';	/* don't copy quotes */
    /* expand "\" escapes, e.g. "\t" to tab character  */
    t = yytext+1;
    while(*t) {
	if (*t == '\\') {
	    t++;
	    switch (*t) {
	      case 'a':
		bbAppend(s,'\007'); t++; /* will use '\a' when STDC */
		break;
	      case 'b':
		bbAppend(s,'\b'); t++;
		break;
	      case 'f':
		bbAppend(s,'\f'); t++;
		break;
	      case 'n':
		bbAppend(s,'\n'); t++;
		break;
	      case 'r':
		bbAppend(s,'\r'); t++;
		break;
	      case 't':
		bbAppend(s,'\t'); t++;
		break;
	      case 'v':
		bbAppend(s,'\v'); t++;
		break;
	      case '\\':
		bbAppend(s,'\\'); t++;
		break;
	      case '?':
		bbAppend(s,'\177'); t++;
		break;
	      case '\'':
		bbAppend(s,'\''); t++;
		break;
	      case '\"':
		bbAppend(s,'\"'); t++;
		break;
	      case 'x':
		t++; /* now t points to one or more hex digits */
		bbAppend(s,(char) strtol(t, &endp, 16));
		t = endp;
		break;
	      case '0':
	      case '1':
	      case '2':
	      case '3':
	      case '4':
	      case '5':
	      case '6':
	      case '7':
		/* t now points to octal digits */
		bbAppend(s,(char) strtol(t, &endp, 8));
		t = endp;
		break;
	      default:
		bbAppend(s,*t); t++;
		break;
	    }
	} else {
	    bbAppend(s,*t); t++;
	}
    }
    bbNull(s);
    bbSetlength(s,strlen(bbContents(s)));
    return;
}
Пример #29
0
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);
	}
    }
}