/* Accumulate useful node sets */ NCerror computecdfnodesets3(NCDAPCOMMON* nccomm, CDFtree* tree) { unsigned int i; NClist* varnodes; NClist* allnodes; allnodes = tree->nodes; varnodes = nclistnew(); if(tree->seqnodes == NULL) tree->seqnodes = nclistnew(); if(tree->gridnodes == NULL) tree->gridnodes = nclistnew(); nclistclear(tree->seqnodes); nclistclear(tree->gridnodes); computevarnodes3(nccomm,allnodes,varnodes); nclistfree(tree->varnodes); tree->varnodes = varnodes; varnodes = NULL; /* Now compute other sets of interest */ for(i=0;i<nclistlength(allnodes);i++) { CDFnode* node = (CDFnode*)nclistget(allnodes,i); switch (node->nctype) { case NC_Sequence: nclistpush(tree->seqnodes,(void*)node); break; case NC_Grid: nclistpush(tree->gridnodes,(void*)node); break; default: break; } } return NC_NOERR; }
/* Based on the tactic, determine the set of variables to add */ static void computevarset4(NCDRNO* drno, Getvara* getvar, NClist* varlist) { int i; nclistclear(varlist); for(i=0;i<nclistlength(drno->cdf.varnodes);i++) { CDFnode* var = (CDFnode*)nclistget(drno->cdf.varnodes,i); #ifdef IGNORE int ok = 1; for(j=0;j<nclistlength(var->array.ncdimensions);j++) { CDFnode* dim = (CDFnode*)nclistget(var->array.ncdimensions,j); if(dim->dim.declsize == NC_UNLIMITED) {ok = 0; break;} } if(!ok) continue; #endif switch (getvar->tactic->tactic) { case tactic_all: /* add all visible variables */ nclistpush(varlist,(ncelem)var); break; case tactic_partial: /* add only small variables + target */ if(var->estimatedsize < drno->cdf.smallsizelimit || getvar->target == var) { nclistpush(varlist,(ncelem)var); } break; case tactic_var: /* add only target var */ if(getvar->target == var) nclistpush(varlist,(ncelem)var); break; default: break; } } }
static void defdimensions(OCddsnode ocnode, CDFnode* cdfnode, NCDAPCOMMON* nccomm, CDFtree* tree) { size_t i,ocrank; oc_dds_rank(nccomm->oc.conn,ocnode,&ocrank); assert(ocrank > 0); for(i=0;i<ocrank;i++) { CDFnode* cdfdim; OCddsnode ocdim; char* ocname; size_t declsize; oc_dds_ithdimension(nccomm->oc.conn,ocnode,i,&ocdim); oc_dimension_properties(nccomm->oc.conn,ocdim,&declsize,&ocname); cdfdim = makecdfnode(nccomm,ocname,OC_Dimension, ocdim,cdfnode->container); nullfree(ocname); nclistpush(tree->nodes,(void*)cdfdim); /* Initially, constrained and unconstrained are same */ cdfdim->dim.declsize = declsize; cdfdim->dim.array = cdfnode; if(cdfnode->array.dimset0 == NULL) cdfnode->array.dimset0 = nclistnew(); nclistpush(cdfnode->array.dimset0,(void*)cdfdim); } }
/* Extract data for a netcdf variable that has a string dimension. */ static int extractstring( NCDAPCOMMON* nccomm, Getvara* xgetvar, CDFnode* xnode, DCEsegment* segment, size_t dimindex, /*notused*/ OClink conn, OCdatanode currentcontent, struct NCMEMORY* memory ) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; int i; size_t rank0; NClist* strings = NULL; Dapodometer* odom = NULL; ASSERT(xnode->etype == NC_STRING || xnode->etype == NC_URL); /* Compute rank minus string dimension */ rank0 = nclistlength(xnode->array.dimset0); /* keep whole extracted strings stored in an NClist */ strings = nclistnew(); if(rank0 == 0) {/*=> scalar*/ char* value = NULL; ocstat = oc_data_readscalar(conn,currentcontent,sizeof(value),&value); if(ocstat != OC_NOERR) goto done; nclistpush(strings,(void*)value); } else { /* Use the odometer to walk to the appropriate fields*/ odom = dapodom_fromsegment(segment,0,rank0); while(dapodom_more(odom)) { char* value = NULL; ocstat = oc_data_readn(conn,currentcontent,odom->index,1,sizeof(value),&value); if(ocstat != OC_NOERR) goto done; nclistpush(strings,(void*)value); dapodom_next(odom); } dapodom_free(odom); } /* Get each string in turn, slice it by applying the string dimm and store in user supplied memory */ for(i=0;i<nclistlength(strings);i++) { char* s = (char*)nclistget(strings,i); slicestring(conn,s,&segment->slices[rank0],memory); free(s); } nclistfree(strings); done: if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
/* Given two projection lists, merge src into dst taking overlapping projections into acct. Assume that name qualification has occured. Dst will be modified. */ NCerror mergeprojections3(NClist* dst, NClist* src) { int i; NClist* cat = nclistnew(); NCerror ncstat = NC_NOERR; #ifdef DEBUG fprintf(stderr,"mergeprojection: dst = %s\n",dumpprojections(dst)); fprintf(stderr,"mergeprojection: src = %s\n",dumpprojections(src)); #endif ASSERT(dst != NULL); /* get dst concat clone(src) */ nclistsetalloc(cat,nclistlength(dst)+nclistlength(src)); for(i=0;i<nclistlength(dst);i++) { DCEprojection* p = (DCEprojection*)nclistget(dst,i); nclistpush(cat,(ncelem)p); } if(src != NULL) for(i=0;i<nclistlength(src);i++) { DCEprojection* p = (DCEprojection*)nclistget(src,i); nclistpush(cat,(ncelem)dceclone((DCEnode*)p)); } nclistclear(dst); /* Repeatedly pull elements from the concat, merge with all duplicates, and stick into the dst */ while(nclistlength(cat) > 0) { DCEprojection* target = (DCEprojection*)nclistremove(cat,0); if(target == NULL) continue; if(target->discrim != CES_VAR) continue; for(i=0;i<nclistlength(cat);i++) { DCEprojection* p2 = (DCEprojection*)nclistget(cat,i); if(p2 == NULL) continue; if(p2->discrim != CES_VAR) continue; if(target->var->cdfleaf != p2->var->cdfleaf) continue; /* This entry matches our current target; merge */ ncstat = mergeprojection31(target,p2); /* null out this merged entry and release it */ nclistset(cat,i,(ncelem)NULL); dcefree((DCEnode*)p2); } /* Capture the clone */ nclistpush(dst,(ncelem)target); } nclistfree(cat); return ncstat; }
int dcemergeprojectionlists(NClist* dst, NClist* src) { int i; NClist* cat = nclistnew(); int ncstat = NC_NOERR; #ifdef DEBUG fprintf(stderr,"dapmergeprojection: dst = %s\n",dcetostring((DCEnode*)dst)); fprintf(stderr,"dapmergeprojection: src = %s\n",dcetostring((DCEnode*)src)); #endif /* get dst concat clone(src) */ nclistsetalloc(cat,nclistlength(dst)+nclistlength(src)); for(i=0;i<nclistlength(dst);i++) { DCEprojection* p = (DCEprojection*)nclistget(dst,i); nclistpush(cat,(void*)p); } for(i=0;i<nclistlength(src);i++) { DCEprojection* p = (DCEprojection*)nclistget(src,i); nclistpush(cat,(void*)dceclone((DCEnode*)p)); } nclistclear(dst); /* Repeatedly pull elements from the concat, merge with all duplicates, and stick into the dst */ while(nclistlength(cat) > 0) { DCEprojection* target = (DCEprojection*)nclistremove(cat,0); if(target == NULL) continue; if(target->discrim != CES_VAR) continue; for(i=0;i<nclistlength(cat);i++) { DCEprojection* p2 = (DCEprojection*)nclistget(cat,i); if(p2 == NULL) continue; if(p2->discrim != CES_VAR) continue; if(dcesamepath(target->var->segments, p2->var->segments)!=0) continue; /* This entry matches our current target; merge */ ncstat = dcemergeprojections(target,p2); /* null out this merged entry and release it */ nclistset(cat,i,(void*)NULL); dcefree((DCEnode*)p2); } /* Capture the clone */ nclistpush(dst,(void*)target); } nclistfree(cat); return ncstat; }
/* Insert new client param (name,value); return value = 1 => not already defined 0 => param already defined (no change) */ static int nc_urlparaminsert(NClist* params, const char* clientparam, const char* value) { int i; if(params == NULL || clientparam == NULL) return 0; for(i=0;i<nclistlength(params);i+=2) { char* name = (char*)nclistget(params,i); if(strcmp(clientparam,name)==0) return 0; } /* not found, append */ nclistpush(params,(ncelem)strdup(clientparam)); nclistpush(params,(ncelem)nulldup(value)); return 1; }
/* Parse a mode string at the commas and convert to envv form */ static int parseurlmode(const char* modestr, NClist* list) { int stat = NC_NOERR; const char* p = NULL; const char* endp = NULL; if(modestr == NULL || *modestr == '\0') goto done; /* Split modestr at the commas or EOL */ p = modestr; for(;;) { char* s; ptrdiff_t slen; endp = strchr(p,','); if(endp == NULL) endp = p + strlen(p); slen = (endp - p); if((s = malloc(slen+1)) == NULL) {stat = NC_ENOMEM; goto done;} memcpy(s,p,slen); s[slen] = '\0'; nclistpush(list,s); if(*endp == '\0') break; p = endp+1; } done: return check(stat); }
/* Define the dimsetall list for a node = */ static NCerror definedimsetall(NCDAPCOMMON* nccomm/*notused*/, CDFnode* node) { int i; int ncstat = NC_NOERR; NClist* dimsetall = NULL; if(node->container != NULL) { /* We need to clone the parent dimensions because we will be assigning indices vis-a-vis this variable */ dimsetall = clonedimset(nccomm,node->container->array.dimsetall,node); } /* append dimsetplus; */ for(i=0;i<nclistlength(node->array.dimsetplus);i++) { CDFnode* clone = NULL; if(dimsetall == NULL) dimsetall = nclistnew(); clone = (CDFnode*)nclistget(node->array.dimsetplus,i); nclistpush(dimsetall,(void*)clone); } node->array.dimsetall = dimsetall; #ifdef DEBUG1 fprintf(stderr,"dimsetall: |%s|=%d\n",node->ocname,(int)nclistlength(dimsetall)); #endif return ncstat; }
/* This is NOT UNION */ int nclistconcat(NClist* l1, NClist* l2) { unsigned int i; for(i=0;i<nclistlength(l2);i++) nclistpush(l1,nclistget(l2,i)); return 1; }
/* Compute the set of variables referenced in the projections of the input constraint. */ NCerror computeprojectedvars(NCDAPCOMMON* dapcomm, DCEconstraint* constraint) { NCerror ncstat = NC_NOERR; NClist* vars = NULL; int i; vars = nclistnew(); if(dapcomm->cdf.projectedvars != NULL) nclistfree(dapcomm->cdf.projectedvars); dapcomm->cdf.projectedvars = vars; if(constraint == NULL || constraint->projections == NULL) goto done; for(i=0;i<nclistlength(constraint->projections);i++) { CDFnode* node; DCEprojection* proj = (DCEprojection*)nclistget(constraint->projections,i); if(proj->discrim == CES_FCN) continue; /* ignore these */ node = (CDFnode*)proj->var->annotation; if(!nclistcontains(vars,(void*)node)) { nclistpush(vars,(void*)node); } } done: return ncstat; }
/* Return 1 if we can reuse cached data to address the current get_vara request; return 0 otherwise. Target is in the constrained tree space. Currently, if the target matches a cache that is not a whole variable, then match is false. */ int iscached(NCDAPCOMMON* nccomm, CDFnode* target, NCcachenode** cachenodep) { int i,j,found,index; NCcache* cache; NCcachenode* cachenode; found = 0; if(target == NULL) goto done; /* Match the target variable against the prefetch, if any */ /* Note that prefetches are always whole variable */ cache = nccomm->cdf.cache; cachenode = cache->prefetch; if(cachenode!= NULL) { for(found=0,i=0;i<nclistlength(cachenode->vars);i++) { CDFnode* var = (CDFnode*)nclistget(cachenode->vars,i); if(var == target) { if(cachenodep) *cachenodep = cachenode; found=1; goto done; } } } /*search other cache nodes starting at latest first */ index = 0; for(i=nclistlength(cache->nodes)-1;i>=0;i--) { cachenode = (NCcachenode*)nclistget(cache->nodes,i); /* We currently do not try to match constraints; If the cachenode is constrained, then skip it */ if(!cachenode->wholevariable) continue; for(found=0,j=0;j<nclistlength(cachenode->vars);j++) { CDFnode* var = (CDFnode*)nclistget(cachenode->vars,j); if(var == target) {found=1;index=i;break;} } if(found) break; } if(found) { ASSERT((cachenode != NULL)); if(nclistlength(cache->nodes) > 1) { /* Manage the cache nodes as LRU */ nclistremove(cache->nodes,index); nclistpush(cache->nodes,(ncelem)cachenode); } if(cachenodep) *cachenodep = cachenode; } done: #ifdef DEBUG fprintf(stderr,"iscached: search: %s\n",makesimplepathstring3(target)); if(found) fprintf(stderr,"iscached: found: %s\n",dumpcachenode(cachenode)); else fprintf(stderr,"iscached: notfound\n"); #endif return found; }
/* Define the dimsettrans list for a single node */ static NCerror definetransdimset(NCDAPCOMMON* nccomm/*notused*/, CDFnode* node) { int i; int ncstat = NC_NOERR; NClist* dimsettrans = NULL; #ifdef DEBUG1 fprintf(stderr,"dimsettrans3: node=%s/%d\n",node->ocname,nclistlength(node->array.dimset0)); #endif if(node->container != NULL) { /* We need to clone the parent dimensions because we will be assigning indices vis-a-vis this variable */ dimsettrans = clonedimset(nccomm,node->container->array.dimsettrans,node); } /* concat parent dimset0 and dimset;*/ if(dimsettrans == NULL) dimsettrans = nclistnew(); for(i=0;i<nclistlength(node->array.dimset0);i++) { CDFnode* clone = NULL; clone = (CDFnode*)nclistget(node->array.dimset0,i); nclistpush(dimsettrans,(void*)clone); } node->array.dimsettrans = dimsettrans; dimsettrans = NULL; #ifdef DEBUG1 fprintf(stderr,"dimsettrans: |%s|=%d\n",node->ocname,(int)nclistlength(dimsettrans)); #endif return ncstat; }
static OCerror collect_leaves(OClink link, OCddsnode ddsnode, NClist* leaves) { size_t nsubnodes,i; OCerror ocstat = OC_NOERR; OCtype octype; ocstat = oc_dds_octype(link,ddsnode,&octype); if(ocstat != OC_NOERR) goto done; if(octype == OC_Atomic) { nclistpush(leaves,(void*)ddsnode); } else { ocstat = oc_dds_nsubnodes(link,ddsnode,&nsubnodes); if(ocstat != OC_NOERR) goto done; for(i=0;i<nsubnodes;i++) { OCddsnode subnode; ocstat = oc_dds_ithsubnode(link,ddsnode,i,&subnode); if(ocstat != OC_NOERR) goto done; ocstat = collect_leaves(link,subnode,leaves); if(ocstat != OC_NOERR) goto done; } } done: return ocstat; }
static Object collectlist(Object list0, Object decl) { NClist* list = (NClist*)list0; if(list == NULL) list = nclistnew(); nclistpush(list,(void*)decl); return list; }
/** * @internal Parse file properties. * * @param text0 Text properties. * @param pairs list of parsed (key,value) pairs * * @return ::NC_NOERR No error. * @author Dennis Heimbigner */ static int properties_parse(const char* text0, NClist* pairs) { int ret = NC_NOERR; char* p; char* q; char* text = NULL; if(text0 == NULL || strlen(text0) == 0) goto done; text = strdup(text0); if(text == NULL) return NC_ENOMEM; /* For back compatibility with version 1, translate '|' -> ',' */ for(p=text;*p;p++) { if(*p == NCPROPSSEP1) *p = NCPROPSSEP2; } /* Walk and fill in ncinfo */ p = text; while(*p) { char* name = p; char* value = NULL; char* next = NULL; /* Delimit whole (key,value) pair */ q = locate(p,NCPROPSSEP2); if(*q != '\0') /* Never go beyond the final nul term */ *q++ = '\0'; next = q; /* split key and value */ q = locate(p,'='); name = p; *q++ = '\0'; value = q; /* Set up p for next iteration */ p = next; nclistpush(pairs,strdup(name)); nclistpush(pairs,strdup(value)); } done: if(text) free(text); return ret; }
/* Convert a CDFnode var to a projection; include pseudodimensions; always whole variable. */ int dapvar2projection(CDFnode* var, DCEprojection** projectionp) { int i,j; int ncstat = NC_NOERR; NClist* path = nclistnew(); NClist* segments; DCEprojection* projection = NULL; int dimindex; /* Collect the nodes needed to construct the projection segment */ collectnodepath3(var,path,!WITHDATASET); segments = nclistnew(); dimindex = 0; /* point to next subset of slices */ nclistsetalloc(segments,nclistlength(path)); for(i=0;i<nclistlength(path);i++) { DCEsegment* segment = (DCEsegment*)dcecreate(CES_SEGMENT); CDFnode* n = (CDFnode*)nclistget(path,i); int localrank; NClist* dimset; segment->annotation = (void*)n; segment->name = nulldup(n->ocname); /* We need to assign whole slices to each segment */ localrank = nclistlength(n->array.dimsetplus); segment->rank = localrank; dimset = n->array.dimsetplus; for(j=0;j<localrank;j++) { DCEslice* slice; CDFnode* dim; slice = &segment->slices[j]; dim = (CDFnode*)nclistget(dimset,j); ASSERT(dim->dim.declsize0 > 0); dcemakewholeslice(slice,dim->dim.declsize0); } segment->slicesdefined = 1; segment->slicesdeclized = 1; dimindex += localrank; nclistpush(segments,(ncelem)segment); } projection = (DCEprojection*)dcecreate(CES_PROJECT); projection->discrim = CES_VAR; projection->var = (DCEvar*)dcecreate(CES_VAR); projection->var->annotation = (void*)var; projection->var->segments = segments; #ifdef DEBUG1 fprintf(stderr,"dapvar2projection: projection=%s\n", dumpprojection(projection)); #endif nclistfree(path); if(ncstat) dcefree((DCEnode*)projection); else if(projectionp) *projectionp = projection; return ncstat; }
static void ceallnodesr(DCEnode* node, NClist* allnodes, CEsort which) { int i; if(node == NULL) return; if(nclistcontains(allnodes,(ncelem)node)) return; if(which == CES_NIL || node->sort == which) nclistpush(allnodes,(ncelem)node); switch(node->sort) { case CES_FCN: { DCEfcn* fcn = (DCEfcn*)node; for(i=0;i<nclistlength(fcn->args);i++) { ceallnodesr((DCEnode*)nclistget(fcn->args,i),allnodes,which); } } break; case CES_VAR: { DCEvar* var = (DCEvar*)node; for(i=0;i<nclistlength(var->segments);i++) { ceallnodesr((DCEnode*)nclistget(var->segments,i),allnodes,which); } } break; case CES_VALUE: { DCEvalue* value = (DCEvalue*)node; if(value->discrim == CES_VAR) ceallnodesr((DCEnode*)value->var,allnodes,which); else if(value->discrim == CES_FCN) ceallnodesr((DCEnode*)value->fcn,allnodes,which); else ceallnodesr((DCEnode*)value->constant,allnodes,which); } break; case CES_SELECT: { DCEselection* selection = (DCEselection*)node; ceallnodesr((DCEnode*)selection->lhs,allnodes,which); for(i=0;i<nclistlength(selection->rhs);i++) ceallnodesr((DCEnode*)nclistget(selection->rhs,i),allnodes,which); } break; case CES_PROJECT: { DCEprojection* projection = (DCEprojection*)node; if(projection->discrim == CES_VAR) ceallnodesr((DCEnode*)projection->var,allnodes,which); else ceallnodesr((DCEnode*)projection->fcn,allnodes,which); } break; case CES_CONSTRAINT: { DCEconstraint* constraint = (DCEconstraint*)node; for(i=0;i<nclistlength(constraint->projections);i++) ceallnodesr((DCEnode*)nclistget(constraint->projections,i),allnodes,which); for(i=0;i<nclistlength(constraint->selections);i++) ceallnodesr((DCEnode*)nclistget(constraint->selections,i),allnodes,which); } break; /* All others have no subnodes */ default: break; } }
static void collectsegmentnames3(NClist* segments, NClist* path) { int i; ncbytesclear(path); for(i=0;i<nclistlength(segments);i++) { DCEsegment* segment = (DCEsegment*)nclistget(segments,i); nclistpush(path,(ncelem)segment->name); } }
/* Collect the set names of container nodes ending in "container"*/ void clonenodenamepath(CDFnode* node, NClist* path, int withdataset) { if(node == NULL) return; /* stop at the dataset container as well*/ if(node->nctype != NC_Dataset) clonenodenamepath(node->container,path,withdataset); if(node->nctype != NC_Dataset || withdataset) nclistpush(path,(void*)nulldup(node->ncbasename)); }
/* Collect the set of container nodes ending in "container"*/ void collectnodepath(CDFnode* node, NClist* path, int withdataset) { if(node == NULL) return; nclistpush(path,(void*)node); while(node->container != NULL) { node = node->container; if(!withdataset && node->nctype == NC_Dataset) break; nclistinsert(path,0,(void*)node); } }
/* Overwrite if already there*/ int nchashreplace(NChashmap* hm, nchashid hash, void* value) { int i,offset,len; NClist* seq; void** list; offset = (hash % hm->alloc); seq = hm->table[offset]; if(seq == NULL) {seq = nclistnew(); hm->table[offset] = seq;} len = nclistlength(seq); list = nclistcontents(seq); for(i=0;i<len;i+=2,list+=2) { if(hash==(nchashid)(*list)) {list[1] = value; return TRUE;} } nclistpush(seq,(void*)hash); nclistpush(seq,value); hm->size++; return TRUE; }
char* dapdecode(DAPlexstate* lexstate, char* name) { char* decoded = NULL; #ifdef DECODE_PARTIAL decoded = ncuridecodepartial(name,decodeset); /* Decode selected */ #else decoded = ncuridecode(name); /* Decode everything */ #endif nclistpush(lexstate->reclaim,(void*)decoded); return decoded; }
/* Collect the set of parent group nodes of node */ void crcollectnodepath(CRnode* node, NClist* path) { Group* group; if(node == NULL) return; nclistpush(path,(ncelem)node); group = node->group; while(group != NULL) { nclistinsert(path,0,(ncelem)group); group = ((CRnode*)group)->group; } }
Object segmentlist(DCEparsestate* state, Object var0, Object decl) { /* watch out: this is non-standard */ NClist* list; DCEvar* v = (DCEvar*)var0; if(v==NULL) v = (DCEvar*)dcecreate(CES_VAR); list = v->segments; if(list == NULL) list = nclistnew(); nclistpush(list,(void*)decl); v->segments = list; return v; }
static CDFnode* clonedim(NCDAPCOMMON* nccomm, CDFnode* dim, CDFnode* var) { CDFnode* clone; clone = makecdfnode(nccomm,dim->ocname,OC_Dimension, NULL,dim->container); /* Record its existence */ nclistpush(dim->container->root->tree->nodes,(void*)clone); clone->dim = dim->dim; /* copy most everything */ clone->dim.dimflags |= CDFDIMCLONE; clone->dim.array = var; return clone; }
static size_t HeaderCallback(char *buffer, size_t size, size_t nitems, void *data) { NClist* list = data; size_t realsize = size * nitems; char* name = NULL; char* value = NULL; char* p = NULL; size_t i; int havecolon; Trace("HeaderCallback"); if(realsize == 0) nclog(NCLOGWARN,"HeaderCallback: zero sized chunk"); i = 0; /* Look for colon separator */ for(p=buffer;(i < realsize) && (*p != ':');p++,i++); havecolon = (i < realsize); if(i == 0) nclog(NCLOGWARN,"HeaderCallback: malformed header: %s",buffer); name = malloc(i+1); memcpy(name,buffer,i); name[i] = '\0'; value = NULL; if(havecolon) { size_t vlen = (realsize - i); value = malloc(vlen+1); p++; /* skip colon */ memcpy(value,p,vlen); value[vlen] = '\0'; trim(value); } nclistpush(list,name); name = NULL; if(value == NULL) value = strdup(""); nclistpush(list,value); value = NULL; return realsize; }
/* Like collectnodepath3, but in ocspace */ void collectocpath(OClink conn, OCddsnode node, NClist* path) { OCddsnode container; OCtype octype; if(node == NULL) return; oc_dds_class(conn,node,&octype); if(octype != OC_Dataset) { oc_dds_container(conn,node,&container); if(container != NULL) collectocpath(conn,container,path); } nclistpush(path,(void*)node); }
Object sel_clause(DCEparsestate* state, int selcase, Object lhs, Object relop0, Object values) { DCEselection* sel = (DCEselection*)dcecreate(CES_SELECT); sel->operator = (CEsort)relop0; sel->lhs = (DCEvalue*)lhs; if(selcase == 2) {/*singleton value*/ sel->rhs = nclistnew(); nclistpush(sel->rhs,(void*)values); } else sel->rhs = (NClist*)values; return sel; }
NClist* dceclonelist(NClist* list) { int i; NClist* clone; if(list == NULL) return NULL; clone = nclistnew(); for(i=0;i<nclistlength(list);i++) { DCEnode* node = (DCEnode*)nclistget(list,i); DCEnode* newnode = dceclone((DCEnode*)node); nclistpush(clone,(ncelem)newnode); } return clone; }