char* decodify(const char *name0) { const unsigned char *cp; unsigned int c; char* name; if(init == 0) initdecodify(); bbClear(newname); cp = (const unsigned char*) name0; if('0' <= *cp && *cp <= '9') { /* handle initial digit, if any */ char tmp[16]; snprintf(tmp,sizeof(tmp),"DIGIT_%c_", *cp); bbCat(newname,tmp); cp++; } while((c=*cp++)) { /* copy name to newname, replacing special chars */ ASSERT(c <= 256); bbCat(newname,repls[c]); } /* If FORTRAN, remove leading _, if any */ name = bbContents(newname); if(bbGet(newname,0) == '_') name++; return pooldup(name); }
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 */
static int f77_constant(Generator* generator, NCConstant* ci, Bytebuffer* codebuf,...) { char tmp[64]; char* special = NULL; switch (ci->nctype) { case NC_CHAR: if(ci->value.charv == '\'') sprintf(tmp,"'\\''"); else sprintf(tmp,"'%c'",ci->value.charv); break; case NC_BYTE: sprintf(tmp,"%hhd",ci->value.int8v); break; case NC_SHORT: sprintf(tmp,"%hd",ci->value.int16v); break; case NC_INT: sprintf(tmp,"%d",ci->value.int32v); break; case NC_FLOAT: sprintf(tmp,"%.8g",ci->value.floatv); break; case NC_DOUBLE: { char* p = tmp; /* FORTRAN requires e|E->D */ sprintf(tmp,"%.16g",ci->value.doublev); while(*p) {if(*p == 'e' || *p == 'E') {*p = 'D';}; p++;} } break; case NC_STRING: { Bytebuffer* buf = bbNew(); bbAppendn(buf,ci->value.stringv.stringv,ci->value.stringv.len); f77quotestring(buf); special = bbDup(buf); bbFree(buf); } break; default: PANIC1("f77data: bad type code: %d",ci->nctype); } if(special != NULL) bbCat(codebuf,special); else bbCat(codebuf,tmp); return 1; }
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; } } }
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; }
/* 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); } } } }
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; }
void codelined(int n, const char* txt) { bbindent(codebuffer,n); bbCat(codebuffer,txt); codepartial("\n"); }
/* 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; }
static int j_list(Generator* generator, Symbol* sym, void* liststate, ListClass lc, int uid, size_t count, Bytebuffer* codebuf, ...) { switch (lc) { case LISTATTR: if(count > 0) bbCat(codebuf,", "); break; case LISTDATA: bbCat(codebuf," "); break; case LISTVLEN: case LISTCOMPOUND: case LISTFIELDARRAY: break; } return 1; }
void cquotestring(Bytebuffer* databuf, char quote) { char* escaped = escapify(bbContents(databuf),'"',bbLength(databuf)); bbClear(databuf); bbAppend(databuf,quote); bbCat(databuf,escaped); bbAppend(databuf,quote); }
/* 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); }
void bufdump(Datalist* list, Bytebuffer* buf) { int i; NCConstant** dpl; unsigned int count; if(list == NULL) { bbCat(buf,"NULL"); return; } count = list->length; for(dpl=list->data,i=0;i<count;i++,dpl++) { NCConstant* dp = *dpl; switch (dp->nctype) { case NC_COMPOUND: bbCat(buf,"{"); bufdump(dp->value.compoundv,buf); bbCat(buf,"}"); break; case NC_ARRAY: bbCat(buf,"["); bufdump(dp->value.compoundv,buf); bbCat(buf,"]"); break; case NC_VLEN: bbCat(buf,"{*"); bufdump(dp->value.compoundv,buf); bbCat(buf,"}"); break; default: if(isprimplus(dp->nctype) || dp->nctype == NC_FILLVALUE) { bbCat(buf," "); dumpdataprim(dp,buf); } else { char tmp[64]; sprintf(tmp,"?%d? ",dp->nctype); bbCat(buf,tmp); } break; } } }
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,';'); } }
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; }
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; }
static int c_vlendecl(Generator* generator, Bytebuffer* codebuf, Symbol* tsym, int uid, size_t count, ...) { /* Build a bytebuffer to capture the vlen decl */ List* declstack = (List*)generator->state; Bytebuffer* decl = bbNew(); Bytebuffer* vlenbuf; va_list ap; vastart(ap,count); vlenbuf = va_arg(ap, Bytebuffer*); va_end(ap); bbprintf0(decl,"static const %s vlen_%u[] = {", ctypename(tsym->typ.basetype), uid); commify(vlenbuf); bbCatbuf(decl,vlenbuf); bbCat(decl,"} ;"); listpush(declstack,(void*)decl); /* Now generate the reference to buffer */ bbprintf(codebuf,"{%u,(void*)vlen_%u}",count,uid); return 1; }
void codepartial(const char* txt) { bbCat(codebuffer,txt); }
static int j_constant(Generator* generator, Symbol* sym, NCConstant* con, Bytebuffer* buf,...) { Bytebuffer* codetmp = bbNew(); char* special = NULL; switch (con->nctype) { case NC_CHAR: if(con->value.charv == '\'') bbprintf(codetmp,"'\\''"); else bbprintf(codetmp,"'%c'",con->value.charv); break; case NC_BYTE: bbprintf(codetmp,"%hhd",con->value.int8v); break; case NC_SHORT: bbprintf(codetmp,"%hd",con->value.int16v); break; case NC_INT: bbprintf(codetmp,"%d",con->value.int32v); break; case NC_FLOAT: /* Special case for nan */ if(isnan(con->value.floatv)) bbprintf(codetmp,"Float.NaN"); else bbprintf(codetmp,"%f",con->value.floatv); break; case NC_DOUBLE: /* Special case for nan */ if(isnan(con->value.doublev)) bbprintf(codetmp,"Double.NaN"); else bbprintf(codetmp,"%lf",con->value.doublev); break; case NC_UBYTE: bbprintf(codetmp,"%hhu",con->value.uint8v); break; case NC_USHORT: bbprintf(codetmp,"%hu",con->value.uint16v); break; case NC_UINT: bbprintf(codetmp,"%uU",con->value.uint32v); break; case NC_INT64: bbprintf(codetmp,"%lldLL",con->value.int64v); break; case NC_UINT64: bbprintf(codetmp,"%lluLLU",con->value.uint64v); break; case NC_STRING: { /* handle separately */ char* escaped = escapify(con->value.stringv.stringv, '"',con->value.stringv.len); special = poolalloc(1+2+strlen(escaped)); strcpy(special,"\""); strcat(special,escaped); strcat(special,"\""); } break; default: PANIC1("ncstype: bad type code: %d",con->nctype); } if(special == NULL) bbCatbuf(buf,codetmp); else bbCat(buf,special); bbFree(codetmp); return 1; }
static void dumpdataprim(NCConstant* ci, Bytebuffer* buf) { char tmp[64]; ASSERT(isprimplus(ci->nctype) || ci->nctype == NC_FILLVALUE); switch (ci->nctype) { case NC_CHAR: { bbCat(buf,"'"); escapifychar(ci->value.charv,tmp,'\''); bbCat(buf,tmp); bbCat(buf,"'"); } break; case NC_BYTE: sprintf(tmp,"%hhd",ci->value.int8v); bbCat(buf,tmp); break; case NC_SHORT: sprintf(tmp,"%hd",ci->value.int16v); bbCat(buf,tmp); break; case NC_INT: sprintf(tmp,"%d",ci->value.int32v); bbCat(buf,tmp); break; case NC_FLOAT: sprintf(tmp,"%g",ci->value.floatv); bbCat(buf,tmp); break; case NC_DOUBLE: sprintf(tmp,"%lg",ci->value.doublev); bbCat(buf,tmp); break; case NC_UBYTE: sprintf(tmp,"%hhu",ci->value.int8v); bbCat(buf,tmp); break; case NC_USHORT: sprintf(tmp,"%hu",ci->value.uint16v); bbCat(buf,tmp); break; case NC_UINT: sprintf(tmp,"%u",ci->value.uint32v); bbCat(buf,tmp); break; case NC_INT64: sprintf(tmp,"%lld",ci->value.int64v); bbCat(buf,tmp); break; case NC_UINT64: sprintf(tmp,"%llu",ci->value.uint64v); bbCat(buf,tmp); break; case NC_ECONST: sprintf(tmp,"%s",ci->value.enumv->fqn); bbCat(buf,tmp); break; case NC_STRING: bbCat(buf,"\""); bbCat(buf,ci->value.stringv.stringv); bbCat(buf,"\""); break; case NC_OPAQUE: bbCat(buf,"0x"); bbCat(buf,ci->value.opaquev.stringv); break; case NC_FILLVALUE: bbCat(buf,"_"); break; default: PANIC1("dumpdataprim: bad type code:%d",ci->nctype); } }
/* Result is a pool string or a constant => do not free*/ char* cdata_const(Constant* ci) { Bytebuffer* codetmp = bbNew(); char* result; switch (ci->nctype) { case NC_CHAR: { char tmp[64]; tmp[0] = '\0'; escapifychar(ci->value.charv,tmp,'\''); bbCat(codetmp,"'"); bbCat(codetmp,tmp); bbCat(codetmp,"'"); } break; case NC_BYTE: bbprintf(codetmp,"%hhd",ci->value.int8v); break; case NC_SHORT: bbprintf(codetmp,"%hd",ci->value.int16v); break; case NC_INT: bbprintf(codetmp,"%d",ci->value.int32v); break; case NC_FLOAT: bbprintf(codetmp,"%f",ci->value.floatv); break; case NC_DOUBLE: bbprintf(codetmp,"%lf",ci->value.doublev); break; case NC_UBYTE: bbprintf(codetmp,"%hhu",ci->value.uint8v); break; case NC_USHORT: bbprintf(codetmp,"%hu",ci->value.uint16v); break; case NC_UINT: bbprintf(codetmp,"%uU",ci->value.uint32v); break; case NC_INT64: bbprintf(codetmp,"%lldLL",ci->value.int64v); break; case NC_UINT64: bbprintf(codetmp,"%lluLLU",ci->value.uint64v); break; case NC_ECONST: bbprintf(codetmp,"%s",cname(ci->value.enumv)); break; case NC_STRING: { /* handle separately */ char* escaped = escapify(ci->value.stringv.stringv, '"',ci->value.stringv.len); result = poolalloc(1+2+strlen(escaped)); strcpy(result,"\""); strcat(result,escaped); strcat(result,"\""); goto done; } break; case NC_OPAQUE: { char* p; int bslen; bslen=(4*ci->value.opaquev.len); result = poolalloc(bslen+2+1); strcpy(result,"\""); p = ci->value.opaquev.stringv; while(*p) { strcat(result,"\\x"); strncat(result,p,2); p += 2; } strcat(result,"\""); goto done; } break; default: PANIC1("ncstype: bad type code: %d",ci->nctype); } result = pooldup(bbContents(codetmp)); /*except for NC_STRING and NC_OPAQUE*/ bbFree(codetmp); done: return result; }
void bbindent(Bytebuffer* buf, const int n) { bbCat(buf,indented(n)); }
static void genjstd_definevardata(Symbol* vsym) { Dimset* dimset = &vsym->typ.dimset; Symbol* basetype = vsym->typ.basetype; int rank = dimset->ndims; int isscalar = (dimset->ndims == 0); Bytebuffer* code; nc_type typecode = basetype->typ.typecode; if(vsym->data == NULL) return; code = bbNew(); jlined(1,"{"); /* Handle special cases first*/ if(isscalar) { /* Construct the data Array */ nprintf(stmt,sizeof(stmt),"Array%s.D0 data = new Array%s.D0();", jtypecap(typecode), jtypecap(typecode)); jlined(1,stmt); /* Fill it */ genjstd_scalardata(vsym,code); if(typecode == NC_CHAR) { nprintf(stmt,sizeof(stmt),"data.set(%s.charAt(0));", bbContents(code)); } else { nprintf(stmt,sizeof(stmt),"data.set((%s)%s);", jtype(typecode),bbContents(code)); } jlined(1,stmt); } else { /* Non-scalar*/ int i; Bytebuffer* dimbuf = bbNew(); /* Store the data */ genjstd_arraydata(vsym,NULL,code); /* Construct the dimension set*/ bbCat(dimbuf,"new int[]{"); for(i=0;i<rank;i++) { Symbol* dsym = dimset->dimsyms[i]; char tmp[32]; if(i==0 && dsym->dim.size == NC_UNLIMITED) nprintf(tmp,sizeof(tmp),"%lu",dsym->dim.unlimitedsize); else nprintf(tmp,sizeof(tmp),"%lu",dsym->dim.size); if(i>0) {bbCat(dimbuf,", ");} bbCat(dimbuf,tmp); } bbCat(dimbuf,"}"); /* Construct the data array and capture its index */ if(typecode == NC_CHAR) nprintf(stmt,sizeof(stmt),"%sString contents = ", indented(1)); else nprintf(stmt,sizeof(stmt),"%s%s[] contents = new %s[] {", indented(1),jtype(typecode),jtype(typecode)); jpartial(stmt); commify(code); jprint(code); if(typecode != NC_CHAR) jpartial("}"); jline(";"); nprintf(stmt,sizeof(stmt),"Array%s data = new Array%s(%s);", jtypecap(typecode), jtypecap(typecode), bbContents(dimbuf)); jlined(1,stmt); jlined(1,"IndexIterator iter = data.getIndexIterator();"); jlined(1,"int count = 0;"); jlined(1,"while(iter.hasNext())"); if(typecode == NC_CHAR) nprintf(stmt,sizeof(stmt), "iter.setCharNext(contents.charAt(count++));"); else nprintf(stmt,sizeof(stmt),"iter.set%sNext(contents[count++]);", jtypecap(typecode)); jlined(2,stmt); bbFree(dimbuf); } /* do the actual write */ nprintf(stmt,sizeof(stmt),"ncfile.write(\"%s\",data);", jescapifyname(vsym->name)); jlined(1,stmt); bbFree(code); jlined(1,"}"); jflush(); }
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(); }
static int c_constant(Generator* generator, NCConstant* con, Bytebuffer* buf,...) { Bytebuffer* codetmp = bbNew(); char* special = NULL; switch (con->nctype) { case NC_CHAR: if(con->value.charv == '\'') bbprintf(codetmp,"'\\''"); else bbprintf(codetmp,"'%s'",cescapifychar(con->value.charv,'\'')); break; case NC_BYTE: bbprintf(codetmp,"%hhd",con->value.int8v); break; case NC_SHORT: bbprintf(codetmp,"%hd",con->value.int16v); break; case NC_INT: bbprintf(codetmp,"%d",con->value.int32v); break; case NC_FLOAT: /* Special case for nanf */ if(isnan(con->value.floatv)) bbprintf(codetmp,"nanf"); else bbprintf(codetmp,"%f",con->value.floatv); break; case NC_DOUBLE: /* Special case for nan */ if(isnan(con->value.doublev)) bbprintf(codetmp,"nan"); else bbprintf(codetmp,"%lf",con->value.doublev); break; case NC_UBYTE: bbprintf(codetmp,"%hhu",con->value.uint8v); break; case NC_USHORT: bbprintf(codetmp,"%hu",con->value.uint16v); break; case NC_UINT: bbprintf(codetmp,"%uU",con->value.uint32v); break; case NC_INT64: bbprintf(codetmp,"%lldLL",con->value.int64v); break; case NC_UINT64: bbprintf(codetmp,"%lluLLU",con->value.uint64v); break; case NC_ECONST: bbprintf(codetmp,"%s",cname(con->value.enumv)); break; case NC_NIL: case NC_STRING: { /* handle separately */ if(con->value.stringv.len == 0 && con->value.stringv.stringv == NULL) { bbprintf(codetmp,"NULL"); } else { char* escaped = escapify(con->value.stringv.stringv, '"',con->value.stringv.len); special = poolalloc(1+2+strlen(escaped)); strcpy(special,"\""); strcat(special,escaped); strcat(special,"\""); } } break; case NC_OPAQUE: { char* p; int bslen; bslen=(4*con->value.opaquev.len); special = poolalloc(bslen+2+1); strcpy(special,"\""); p = con->value.opaquev.stringv; while(*p) { strcat(special,"\\x"); strncat(special,p,2); p += 2; } strcat(special,"\""); } break; default: PANIC1("ncstype: bad type code: %d",con->nctype); } if(special == NULL) bbCatbuf(buf,codetmp); else bbCat(buf,special); bbFree(codetmp); return 1; }
static void genj_writevar(Generator* generator, Symbol* vsym, Bytebuffer* code, int rank, size_t* start, size_t* count) { Dimset* dimset = &vsym->typ.dimset; int typecode = vsym->typ.basetype->typ.typecode; int i; codeline(""); codelined(1,"{"); /* Enclose in {...} for scoping */ if(rank == 0) { bbprintf0(stmt,"%sArray%s.D0 data = new Array%s.D0();\n", indented(1),jtypecap(typecode), jtypecap(typecode)); codedump(stmt); if(typecode == NC_CHAR) { /* Construct the data Array */ jquotestring(code,'\''); bbprintf0(stmt,"%sdata.set((char)%s);\n", indented(1),bbContents(code)); } else { commify(code); bbprintf0(stmt,"%sdata.set((%s)%s);\n", indented(1),jtype(typecode),bbContents(code)); } codedump(stmt); /* do the actual write */ bbprintf0(stmt,"%sncfile.write(\"%s\",data);\n", indented(1),jescapifyname(vsym->name)); codedump(stmt); } else { /* array */ Bytebuffer* dimbuf = bbNew(); /* Construct the dimension set*/ bbCat(dimbuf,"new int[]{"); for(i=0;i<rank;i++) { Symbol* dsym = dimset->dimsyms[i]; char tmp[32]; nprintf(tmp,sizeof(tmp),"%lu",dsym->dim.declsize); if(i>0) {bbCat(dimbuf,", ");} bbCat(dimbuf,tmp); } bbCat(dimbuf,"}"); /* Construct the data array and capture its index */ if(typecode == NC_CHAR) { jquotestring(code,'"'); bbprintf0(stmt,"%sString contents = ", indented(1)); } else { bbprintf0(stmt,"%s%s[] contents = new %s[] {", indented(1),jtype(typecode),jtype(typecode)); commify(code); } codedump(stmt); codedump(code); if(typecode != NC_CHAR) codepartial("}"); codeline(";"); bbprintf0(stmt,"%sArray%s data = new Array%s(%s);\n", indented(1), jtypecap(typecode), jtypecap(typecode), bbContents(dimbuf)); codedump(stmt); codelined(1,"IndexIterator iter = data.getIndexIterator();"); codelined(1,"int count = 0;"); codelined(1,"while(iter.hasNext())"); if(typecode == NC_CHAR) bbprintf0(stmt, "%siter.setCharNext(contents.charAt(count++));\n",indented(2)); else bbprintf0(stmt,"%siter.set%sNext(contents[count++]);\n", indented(2),jtypecap(typecode)); codedump(stmt); bbFree(dimbuf); /* Construct the origin set from the start set */ bbprintf0(stmt,"%sint[] origin = new int[]{",indented(1)); for(i=0;i<rank;i++) { bbprintf(stmt,"%s%lu",(i>0?", ":""),start[i]); } bbCat(stmt,"};\n"); codedump(stmt); /* do the actual write */ bbprintf0(stmt,"%sncfile.write(\"%s\",origin,data);\n", indented(1),jescapifyname(vsym->name)); codedump(stmt); } codelined(1,"}"); /* Enclose in {...} for scoping */ codeflush(); }
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; } }