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); } }
bool GetRemote(int handle, char s[], int size) { if(handle < 0 || handle >= ObjectCount || stack[handle]->tag != LIST) return False; if(seterror() == 0) { Cell *list = stack[handle]; evaluate(list->left); if(list->left->tag != LIST) return False; fillstring(list->left->left, s, size); list->left = list->left->right; return True; } else { setstackheight(ObjectCount); stack[handle] = template_nil; interrupted = False; return False; } }
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); } }