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; }
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 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 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; }
/* 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; }