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 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 srcpush(Datasrc* src) { NCConstant* con; ASSERT(src != NULL); con = srcnext(src); ASSERT(con->nctype == NC_COMPOUND); srcpushlist(src,con->value.compoundv); }
static int stringexplode(Datasrc* src, size_t chunksize) { Constant* con; Datalist* charlist; if(!isstring(src)) return 0; con = srcnext(src); charlist = buildstringlist(con->value.stringv.stringv,chunksize,srcline(src)); srcpushlist(src,charlist); return 1; }
void genbin_fillvalue(Symbol* tsym, Datalist* fillsrc, Datasrc* src, Bytebuffer* memory) { Datalist* list = NULL; ASSERT(tsym->objectclass == NC_TYPE); list = fillsrc; if(list == NULL) list = getfiller(tsym); srcpushlist(src,list); genbin_data(tsym,src,NULL,memory); srcpop(src); }
void srcsplice(Datasrc* ds, Datalist* list) { srcpushlist(ds,list); ds->spliced = 1; }
/* 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); } }
static void genbin_primdata(Symbol* basetype, Datasrc* src, Datalist* fillsrc, Bytebuffer* memory) { Constant* prim; Constant target; prim = srcnext(src); if(prim == NULL || prim->nctype == NC_FILLVALUE) { genbin_fillvalue(basetype,fillsrc,src,memory); return; } target.nctype = basetype->typ.typecode; if(prim == NULL) { #ifdef GENFILL /* generate a fill value*/ nc_getfill(&target); /* fall thru*/ #else return; #endif } ASSERT(prim->nctype != NC_COMPOUND); if(target.nctype != NC_ECONST) { convert1(prim,&target); alignbuffer(&target,memory); } 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); srcpushlist(src,econ); dlappend(econ,&prim->value.enumv->typ.econst); genbin_primdata(prim->value.enumv->typ.basetype,src, fillsrc,memory); srcpop(src); } break; case NC_OPAQUE: { unsigned char* bytes; size_t len; setprimlength(&target,basetype->typ.size*2); bytes=makebytestring(target.value.opaquev.stringv,&len); bbAppendn(memory,(void*)bytes,len); } break; case NC_CHAR: bbAppendn(memory,&target.value.charv,sizeof(target.value.charv)); break; case NC_BYTE: bbAppendn(memory,(void*)&target.value.int8v,sizeof(target.value.int8v)); break; case NC_SHORT: bbAppendn(memory,(void*)&target.value.int16v,sizeof(target.value.int16v)); break; case NC_INT: bbAppendn(memory,(void*)&target.value.int32v,sizeof(target.value.int32v)); break; case NC_FLOAT: bbAppendn(memory,(void*)&target.value.floatv,sizeof(target.value.floatv)); break; case NC_DOUBLE: bbAppendn(memory,(void*)&target.value.doublev,sizeof(target.value.doublev)); break; case NC_UBYTE: bbAppendn(memory,(void*)&target.value.uint8v,sizeof(target.value.uint8v)); break; case NC_USHORT: bbAppendn(memory,(void*)&target.value.uint16v,sizeof(target.value.uint16v)); break; case NC_UINT: bbAppendn(memory,(void*)&target.value.uint32v,sizeof(target.value.uint32v)); break; case NC_INT64: { union SI64 { char ch[8]; long long i64;} si64; si64.i64 = target.value.int64v; bbAppendn(memory,(void*)si64.ch,sizeof(si64.ch)); } break; case NC_UINT64: { union SU64 { char ch[8]; unsigned long long i64;} su64; su64.i64 = target.value.uint64v; bbAppendn(memory,(void*)su64.ch,sizeof(su64.ch)); } break; case NC_STRING: { if(usingclassic) { bbAppendn(memory,target.value.stringv.stringv,target.value.stringv.len); } else if(target.nctype == NC_CHAR) { bbAppendn(memory,target.value.stringv.stringv,target.value.stringv.len); } else { char* ptr; int len = (size_t)target.value.stringv.len; ptr = poolalloc(len+1); /* CAREFUL: this has short lifetime*/ memcpy(ptr,target.value.stringv.stringv,len); ptr[len] = '\0'; bbAppendn(memory,(void*)&ptr,sizeof(ptr)); } } break; default: PANIC1("genbin_primdata: unexpected type: %d",target.nctype); } }