123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866 |
- /*********************************************************************
- * Copyright 1993, UCAR/Unidata
- * See netcdf/COPYRIGHT file for copying and redistribution conditions.
- * $Header: /upc/share/CVS/netcdf-3/libncdap3/constraints3.c,v 1.40 2010/05/27 21:34:07 dmh Exp $
- *********************************************************************/
- #include "config.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- #include "nclist.h"
- #include "ncbytes.h"
- #include "nclog.h"
- #include "netcdf.h"
- #include "dceconstraints.h"
- #include "dapdebug.h"
- #include "dceparselex.h"
- #define DEBUG
- int dceverbose = 0;
- static char* opstrings[] = OPSTRINGS ;
- static void ceallnodesr(DCEnode* node, NClist* allnodes, CEsort which);
- /* Parse incoming url constraints, if any,
- to check for syntactic correctness
- */
- int
- dapparseconstraints(char* constraints, DCEconstraint* dapconstraint)
- {
- int ncstat = NC_NOERR;
- char* errmsg;
- assert(dapconstraint != NULL);
- nclistclear(dapconstraint->projections);
- nclistclear(dapconstraint->selections);
- ncstat = dapceparse(constraints,dapconstraint,&errmsg);
- if(ncstat) {
- nclog(NCLOGWARN,"DAP constraint parse failure: %s",errmsg);
- if(errmsg) free(errmsg);
- nclistclear(dapconstraint->projections);
- nclistclear(dapconstraint->selections);
- }
- #ifdef DEBUG
- fprintf(stderr,"constraint: %s",dcetostring((DCEnode*)dapconstraint));
- #endif
- return ncstat;
- }
- /* Worksheet
- mg.st = md.st * ms.st
- mg.f = md.f+(ms.f*md.st)
- mg.l = ((ms.l-1) / ms.st) * mg.st + 1
- mg.p = mg.f + mg.l
- mg.c = mg.l / mg.st
- 0000000000111111111122222222223
- 0123456789012345678901234567890
- xxxxxx
- xxxxxx
- 0 1 2 3 4 5 6 7 8 md=(st=3 f=1 l=25 p=26)
- 0 1 2 ms=(st=2 f=3 l=5 p=8 )
- ----------------------------
- mg=(st=6 f=10 p=23 l=13)
- c = 4 / 2 = 2
- l = 2 * 6 + 1 = 13
- 0000000000111111
- 0123456789012345
- 0 1 2 3 4 md=(st=2 f=1 l=9 p=10)
- 0 1 2 ms=(st=1 f=2 l=3 p=5)
- ----------------------------
- mg=(st=2 f=5 p=10 l=5 )
- c = 2/1 = 2
- l = 2 * 2 + 1 = 13
- 0000000000111111111
- 0123456789012345678
- 0 1 2 3 4 5 6 7 8 md=(st=2 f=1 l=17 p=18)
- 0 1 2 ms=(st=2 f=3 l=5 p=8)
- ----------------------------
- mg=(st=4 f=7 p=16 l=9 )
- c = 4/2 = 2
- l = 2 * 4 + 1 = 9
- 0000000000111111111
- 0123456789012345678
- 0 1 2 3 4 md=(st=2 f=1 l=9 p=10)
- 0 1 2 3 4 ms=(st=1 f=0 l=5 p=5)
- ----------------------------
- mg=(st=2 f=1 p=10 l=9 )
- c = 4/1 = 4
- l = 4 * 2 + 1 = 9
- 00000
- 01234
- 01 md=(st=1 f=0 l=2 p=2)
- 0 ms=(st=1 f=0 l=1 p=1)
- ----------------------------
- mg=(st=1 f=0 p=1 l=1 )
- c = 0/1 = 0
- l = 0 * 1 + 1 = 1
- 000000000011
- 012345678901
- 012 md=(st=1 f=0 l=3 p=3)
- 012 ms=(st=1 f=0 l=3 p=2)
- ----------------------------
- mg=(st=1 f=0 p=3 l=3 )
- c = 2/1 = 2
- l = 2 * 1 + 1 = 3
- */
- /* Merge slice src into slice dst; dst != src */
- int
- dceslicemerge(DCEslice* dst, DCEslice* src)
- {
- int err = NC_NOERR;
- DCEslice tmp;
- tmp.node.sort = CES_SLICE;
- tmp.stride = (dst->stride * src->stride);
- tmp.first = (dst->first+((src->first)*(dst->stride)));
- tmp.length = (((src->length - 1) / src->stride) * tmp.stride) + 1;
- tmp.stop = tmp.first + tmp.length;
- tmp.count = tmp.length / tmp.stride;
- /* use max declsize */
- if(dst->declsize > src->declsize) {
- tmp.declsize = dst->declsize;
- } else {
- tmp.declsize = src->declsize;
- }
- if(tmp.length % tmp.stride != 0) tmp.count++;
- if(tmp.first >= dst->stop || tmp.stop > dst->stop)
- err = NC_EINVALCOORDS;
- else
- *dst = tmp;
- return err;
- }
- /*
- Given two projection lists, merge
- src into dst taking
- overlapping projections into acct.
- */
- 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,(ncelem)p);
- }
- 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(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,(ncelem)NULL);
- dcefree((DCEnode*)p2);
- }
- /* Capture the clone */
- nclistpush(dst,(ncelem)target);
- }
- nclistfree(cat);
- return ncstat;
- }
- /* Modify merged projection to include "addition" projection */
- int
- dcemergeprojections(DCEprojection* merged, DCEprojection* addition)
- {
- int ncstat = NC_NOERR;
- int i,j;
- ASSERT((merged->discrim == CES_VAR && addition->discrim == CES_VAR));
- ASSERT((nclistlength(merged->var->segments) == nclistlength(addition->var->segments)));
- for(i=0;i<nclistlength(merged->var->segments);i++) {
- DCEsegment* mergedseg = (DCEsegment*)nclistget(merged->var->segments,i);
- DCEsegment* addedseg = (DCEsegment*)nclistget(addition->var->segments,i);
- /* If one segment has larger rank, then copy the extra slices unchanged */
- for(j=0;j<addedseg->rank;j++) {
- if(j < mergedseg->rank)
- dceslicemerge(mergedseg->slices+j,addedseg->slices+j);
- else
- mergedseg->slices[j] = addedseg->slices[j];
- }
- if(addedseg->rank > mergedseg->rank)
- mergedseg->rank = addedseg->rank;
- }
- return ncstat;
- }
- /* Convert a DCEprojection instance into a string
- that can be used with the url
- */
- char*
- buildprojectionstring(NClist* projections)
- {
- char* pstring;
- NCbytes* buf = ncbytesnew();
- dcelisttobuffer(projections,buf,",");
- pstring = ncbytesdup(buf);
- ncbytesfree(buf);
- return pstring;
- }
- char*
- buildselectionstring(NClist* selections)
- {
- NCbytes* buf = ncbytesnew();
- char* sstring;
- dcelisttobuffer(selections,buf,",");
- sstring = ncbytesdup(buf);
- ncbytesfree(buf);
- return sstring;
- }
- char*
- buildconstraintstring(DCEconstraint* constraints)
- {
- NCbytes* buf = ncbytesnew();
- char* result = NULL;
- dcetobuffer((DCEnode*)constraints,buf);
- result = ncbytesdup(buf);
- ncbytesfree(buf);
- return result;
- }
- DCEnode*
- dceclone(DCEnode* node)
- {
- DCEnode* result = NULL;
- result = (DCEnode*)dcecreate(node->sort);
- if(result == NULL) goto done;
- switch (node->sort) {
- case CES_SLICE: {
- DCEslice* clone = (DCEslice*)result;
- DCEslice* orig = (DCEslice*)node;
- *clone = *orig;
- } break;
- case CES_SEGMENT: {
- DCEsegment* clone = (DCEsegment*)result;
- DCEsegment* orig = (DCEsegment*)node;
- *clone = *orig;
- clone->name = nulldup(orig->name);
- if(orig->rank > 0)
- memcpy(clone->slices,orig->slices,orig->rank*sizeof(DCEslice));
- } break;
- case CES_VAR: {
- DCEvar* clone = (DCEvar*)result;
- DCEvar* orig = (DCEvar*)node;
- *clone = *orig;
- clone->segments = dceclonelist(clone->segments);
- } break;
- case CES_FCN: {
- DCEfcn* clone = (DCEfcn*)result;
- DCEfcn* orig = (DCEfcn*)node;
- *clone = *orig;
- clone->name = nulldup(orig->name);
- clone->args = dceclonelist(orig->args);
- } break;
- case CES_CONST: {
- DCEconstant* clone = (DCEconstant*)result;
- DCEconstant* orig = (DCEconstant*)node;
- *clone = *orig;
- if(clone->discrim == CES_STR)
- clone->text = nulldup(clone->text);
- } break;
- case CES_VALUE: {
- DCEvalue* clone = (DCEvalue*)result;
- DCEvalue* orig = (DCEvalue*)node;
- *clone = *orig;
- switch (clone->discrim) {
- case CES_CONST:
- clone->constant = (DCEconstant*)dceclone((DCEnode*)orig->constant); break;
- case CES_VAR:
- clone->var = (DCEvar*)dceclone((DCEnode*)orig->var); break;
- case CES_FCN:
- clone->fcn = (DCEfcn*)dceclone((DCEnode*)orig->fcn); break;
- default: assert(0);
- }
- } break;
- case CES_PROJECT: {
- DCEprojection* clone = (DCEprojection*)result;
- DCEprojection* orig = (DCEprojection*)node;
- *clone = *orig;
- switch (orig->discrim) {
- case CES_VAR:
- clone->var = (DCEvar*)dceclone((DCEnode*)orig->var); break;
- case CES_FCN:
- clone->fcn = (DCEfcn*)dceclone((DCEnode*)orig->fcn); break;
- default: assert(0);
- }
- } break;
- case CES_SELECT: {
- DCEselection* clone = (DCEselection*)result;
- DCEselection* orig = (DCEselection*)node;
- *clone = *orig;
- clone->lhs = (DCEvalue*)dceclone((DCEnode*)orig->lhs);
- clone->rhs = dceclonelist(orig->rhs);
- } break;
- case CES_CONSTRAINT: {
- DCEconstraint* clone = (DCEconstraint*)result;
- DCEconstraint* orig = (DCEconstraint*)node;
- *clone = *orig;
- clone->projections = dceclonelist(orig->projections);
- clone->selections = dceclonelist(orig->selections);
- } break;
- default:
- assert(0);
- }
- done:
- return result;
- }
- 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;
- }
- void
- dcefree(DCEnode* node)
- {
- if(node == NULL) return;
- switch (node->sort) {
- case CES_VAR: {
- DCEvar* target = (DCEvar*)node;
- dcefreelist(target->segments);
- } break;
- case CES_FCN: {
- DCEfcn* target = (DCEfcn*)node;
- dcefreelist(target->args);
- nullfree(target->name);
- } break;
- case CES_CONST: {
- DCEconstant* target = (DCEconstant*)node;
- if(target->discrim == CES_STR)
- nullfree(target->text);
- } break;
- case CES_VALUE: {
- DCEvalue* target = (DCEvalue*)node;
- switch(target->discrim) {
- case CES_CONST: dcefree((DCEnode*)target->constant); break;
- case CES_VAR: dcefree((DCEnode*)target->var); break;
- case CES_FCN: dcefree((DCEnode*)target->fcn); break;
- default: assert(0);
- }
- } break;
- case CES_PROJECT: {
- DCEprojection* target = (DCEprojection*)node;
- switch (target->discrim) {
- case CES_VAR: dcefree((DCEnode*)target->var); break;
- case CES_FCN: dcefree((DCEnode*)target->fcn); break;
- default: assert(0);
- }
- } break;
- case CES_SELECT: {
- DCEselection* target = (DCEselection*)node;
- dcefreelist(target->rhs);
- dcefree((DCEnode*)target->lhs);
- } break;
- case CES_CONSTRAINT: {
- DCEconstraint* target = (DCEconstraint*)node;
- dcefreelist(target->projections);
- dcefreelist(target->selections);
- } break;
- case CES_SEGMENT: {
- DCEsegment* target = (DCEsegment*)node;
- target->rank = 0;
- nullfree(target->name);
- } break;
- case CES_SLICE: {
- } break;
- default:
- assert(0);
- }
- /* final action */
- free(node);
- }
- void
- dcefreelist(NClist* list)
- {
- int i;
- if(list == NULL) return;
- for(i=0;i<nclistlength(list);i++) {
- DCEnode* node = (DCEnode*)nclistget(list,i);
- dcefree((DCEnode*)node);
- }
- nclistfree(list);
- }
- char*
- dcetostring(DCEnode* node)
- {
- char* s;
- NCbytes* buf = ncbytesnew();
- dcetobuffer(node,buf);
- s = ncbytesextract(buf);
- ncbytesfree(buf);
- return s;
- }
- /* For debugging */
- #ifdef DEBUG
- static char*
- dimdecl(size_t declsize)
- {
- static char tag[16];
- tag[0] = '\0';
- if(dceverbose)
- snprintf(tag,sizeof(tag),"/%lu",(unsigned long)declsize);
- return tag;
- }
- #else
- static char*
- dimdecl(size_t declsize)
- {
- return "";
- }
- #endif
- void
- dcetobuffer(DCEnode* node, NCbytes* buf)
- {
- int i;
- char tmp[1024];
- if(buf == NULL) return;
- if(node == NULL) {ncbytescat(buf,"<null>"); return;}
- switch (node->sort) {
- case CES_SLICE: {
- DCEslice* slice = (DCEslice*)node;
- size_t last = (slice->first+slice->length)-1;
- if(slice->count == 1) {
- snprintf(tmp,sizeof(tmp),"[%lu%s]",
- (unsigned long)slice->first,dimdecl(slice->declsize));
- } else if(slice->stride == 1) {
- snprintf(tmp,sizeof(tmp),"[%lu:%lu%s]",
- (unsigned long)slice->first,
- (unsigned long)last,
- dimdecl(slice->declsize));
- } else {
- snprintf(tmp,sizeof(tmp),"[%lu:%lu:%lu%s]",
- (unsigned long)slice->first,
- (unsigned long)slice->stride,
- (unsigned long)last,
- dimdecl(slice->declsize));
- }
- ncbytescat(buf,tmp);
- } break;
- case CES_SEGMENT: {
- DCEsegment* segment = (DCEsegment*)node;
- int rank = segment->rank;
- char* name = (segment->name?segment->name:"<unknown>");
- name = nulldup(name);
- ncbytescat(buf,name);
- nullfree(name);
- if(dceverbose && dceiswholesegment(segment))
- ncbytescat(buf,"*");
- if(dceverbose || !dceiswholesegment(segment)) {
- for(i=0;i<rank;i++) {
- DCEslice* slice = segment->slices+i;
- dcetobuffer((DCEnode*)slice,buf);
- }
- }
- } break;
- case CES_VAR: {
- DCEvar* var = (DCEvar*)node;
- dcelisttobuffer(var->segments,buf,".");
- } break;
- case CES_FCN: {
- DCEfcn* fcn = (DCEfcn*)node;
- ncbytescat(buf,fcn->name);
- ncbytescat(buf,"(");
- dcelisttobuffer(fcn->args,buf,",");
- ncbytescat(buf,")");
- } break;
- case CES_CONST: {
- DCEconstant* value = (DCEconstant*)node;
- switch (value->discrim) {
- case CES_STR:
- ncbytescat(buf,value->text);
- break;
- case CES_INT:
- snprintf(tmp,sizeof(tmp),"%lld",value->intvalue);
- ncbytescat(buf,tmp);
- break;
- case CES_FLOAT:
- snprintf(tmp,sizeof(tmp),"%g",value->floatvalue);
- ncbytescat(buf,tmp);
- break;
- default: assert(0);
- }
- } break;
- case CES_VALUE: {
- DCEvalue* value = (DCEvalue*)node;
- switch (value->discrim) {
- case CES_CONST:
- dcetobuffer((DCEnode*)value->constant,buf);
- break;
- case CES_VAR:
- dcetobuffer((DCEnode*)value->var,buf);
- break;
- case CES_FCN:
- dcetobuffer((DCEnode*)value->fcn,buf);
- break;
- default: assert(0);
- }
- } break;
- case CES_PROJECT: {
- DCEprojection* target = (DCEprojection*)node;
- switch (target->discrim) {
- case CES_VAR:
- dcetobuffer((DCEnode*)target->var,buf);
- break;
- case CES_FCN: dcetobuffer((DCEnode*)target->fcn,buf); break;
- default: assert(0);
- }
- } break;
- case CES_SELECT: {
- DCEselection* sel = (DCEselection*)node;
- dcetobuffer((DCEnode*)sel->lhs,buf);
- if(sel->operator == CES_NIL) break;
- ncbytescat(buf,opstrings[(int)sel->operator]);
- if(nclistlength(sel->rhs) > 1)
- ncbytescat(buf,"{");
- dcelisttobuffer(sel->rhs,buf,",");
- if(nclistlength(sel->rhs) > 1)
- ncbytescat(buf,"}");
- } break;
- case CES_CONSTRAINT: {
- DCEconstraint* con = (DCEconstraint*)node;
- if(con->projections != NULL && nclistlength(con->projections) > 0) {
- dcelisttobuffer(con->projections,buf,",");
- }
- if(con->selections != NULL && nclistlength(con->selections) > 0) {
- ncbytescat(buf,"&"); /* because & is really a prefix */
- dcelisttobuffer(con->selections,buf,"&");
- }
- } break;
- case CES_NIL: {
- ncbytescat(buf,"<nil>");
- } break;
- default:
- assert(0);
- }
- }
- char*
- dcelisttostring(NClist* list, char* sep)
- {
- char* s;
- NCbytes* buf = ncbytesnew();
- dcelisttobuffer(list,buf,sep);
- s = ncbytesextract(buf);
- ncbytesfree(buf);
- return s;
- }
- void
- dcelisttobuffer(NClist* list, NCbytes* buf, char* sep)
- {
- int i;
- if(list == NULL || buf == NULL) return;
- if(sep == NULL) sep = ",";
- for(i=0;i<nclistlength(list);i++) {
- DCEnode* node = (DCEnode*)nclistget(list,i);
- if(node == NULL) continue;
- if(i>0) ncbytescat(buf,sep);
- dcetobuffer((DCEnode*)node,buf);
- }
- }
- /* Collect all nodes within a specified constraint tree */
- /* Caller frees result */
- NClist*
- dceallnodes(DCEnode* node, CEsort which)
- {
- NClist* allnodes = nclistnew();
- ceallnodesr(node,allnodes,which);
- return allnodes;
- }
- 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;
- }
- }
- DCEnode*
- dcecreate(CEsort sort)
- {
- DCEnode* node = NULL;
- switch (sort) {
- case CES_SLICE: {
- DCEslice* target = (DCEslice*)calloc(1,sizeof(DCEslice));
- if(target == NULL) return NULL;
- node = (DCEnode*)target;
- } break;
- case CES_SEGMENT: {
- int i;
- DCEsegment* target = (DCEsegment*)calloc(1,sizeof(DCEsegment));
- if(target == NULL) return NULL;
- /* Initialize the sort of the slices */
- for(i=0;i<NC_MAX_VAR_DIMS;i++)
- target->slices[i].node.sort = CES_SLICE;
- node = (DCEnode*)target;
- } break;
- case CES_CONST: {
- DCEconstant* target = (DCEconstant*)calloc(1,sizeof(DCEconstant));
- if(target == NULL) return NULL;
- node = (DCEnode*)target;
- target->discrim = CES_NIL;
- } break;
- case CES_VALUE: {
- DCEvalue* target = (DCEvalue*)calloc(1,sizeof(DCEvalue));
- if(target == NULL) return NULL;
- node = (DCEnode*)target;
- target->discrim = CES_NIL;
- } break;
- case CES_VAR: {
- DCEvar* target = (DCEvar*)calloc(1,sizeof(DCEvar));
- if(target == NULL) return NULL;
- node = (DCEnode*)target;
- } break;
- case CES_FCN: {
- DCEfcn* target = (DCEfcn*)calloc(1,sizeof(DCEfcn));
- if(target == NULL) return NULL;
- node = (DCEnode*)target;
- } break;
- case CES_PROJECT: {
- DCEprojection* target = (DCEprojection*)calloc(1,sizeof(DCEprojection));
- if(target == NULL) return NULL;
- node = (DCEnode*)target;
- } break;
- case CES_SELECT: {
- DCEselection* target = (DCEselection*)calloc(1,sizeof(DCEselection));
- if(target == NULL) return NULL;
- node = (DCEnode*)target;
- target->operator = CEO_NIL;
- } break;
- case CES_CONSTRAINT: {
- DCEconstraint* target = (DCEconstraint*)calloc(1,sizeof(DCEconstraint));
- if(target == NULL) return NULL;
- node = (DCEnode*)target;
- } break;
- default:
- assert(0);
- }
- /* final action */
- node->sort = sort;
- return node;
- }
- int
- dceiswholeslice(DCEslice* slice)
- {
- if(slice->first != 0
- || slice->stride != 1
- || slice->stop != slice->declsize) return 0;
- return 1;
- }
- int
- dceiswholesegment(DCEsegment* seg)
- {
- int i,whole;
-
- if(!seg->slicesdefined) return 0; /* actually, we don't know */
- whole = 1; /* assume so */
- for(i=0;i<seg->rank;i++) {
- if(!dceiswholeslice(&seg->slices[i])) {whole = 0; break;}
- }
- return whole;
- }
- void
- dcemakewholeslice(DCEslice* slice, size_t declsize)
- {
- slice->first = 0;
- slice->stride = 1;
- slice->length = declsize;
- slice->stop = declsize;
- slice->declsize = declsize;
- slice->count = declsize;
- }
- /* Remove slicing from terminal segment of p */
- void
- dcemakewholeprojection(DCEprojection* p)
- {
- /* Remove the slicing (if any) from the last segment */
- if(p->discrim == CES_VAR && p->var != NULL && p->var->segments != NULL) {
- int lastindex = nclistlength(p->var->segments) - 1;
- DCEsegment* lastseg = (DCEsegment*)nclistget(p->var->segments,lastindex);
- lastseg->rank = 0;
- }
- }
- int
- dcesamepath(NClist* list1, NClist* list2)
- {
- int i;
- int len = nclistlength(list1);
- if(len != nclistlength(list2)) return 0;
- for(i=0;i<len;i++) {
- DCEsegment* s1 = (DCEsegment*)nclistget(list1,i);
- DCEsegment* s2 = (DCEsegment*)nclistget(list2,i);
- if(strcmp(s1->name,s2->name) != 0) return 0;
- }
- return 1;
- }
|