source: XIOS/trunk/extern/src_netcdf4/dceconstraints.c @ 409

Last change on this file since 409 was 409, checked in by ymipsl, 11 years ago

Add improved nectdf internal library src

YM

  • Property svn:eol-style set to native
File size: 21.8 KB
Line 
1/*********************************************************************
2 *   Copyright 1993, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *   $Header: /upc/share/CVS/netcdf-3/libncdap3/constraints3.c,v 1.40 2010/05/27 21:34:07 dmh Exp $
5 *********************************************************************/
6
7#include "config.h"
8
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12#include <assert.h>
13
14#include "nclist.h"
15#include "ncbytes.h"
16#include "nclog.h"
17
18#include "netcdf.h"
19#include "dceconstraints.h"
20#include "dapdebug.h"
21#include "dceparselex.h"
22
23#define DEBUG
24
25int dceverbose = 0;
26
27static char* opstrings[] = OPSTRINGS ;
28
29static void ceallnodesr(DCEnode* node, NClist* allnodes, CEsort which);
30
31/* Parse incoming url constraints, if any,
32   to check for syntactic correctness
33*/ 
34int
35dapparseconstraints(char* constraints, DCEconstraint* dapconstraint)
36{
37    int ncstat = NC_NOERR;
38    char* errmsg;
39
40    assert(dapconstraint != NULL);
41    nclistclear(dapconstraint->projections);
42    nclistclear(dapconstraint->selections);
43
44    ncstat = dapceparse(constraints,dapconstraint,&errmsg);
45    if(ncstat) {
46        nclog(NCLOGWARN,"DAP constraint parse failure: %s",errmsg);
47        if(errmsg) free(errmsg);
48        nclistclear(dapconstraint->projections);
49        nclistclear(dapconstraint->selections);
50    }
51
52#ifdef DEBUG
53fprintf(stderr,"constraint: %s",dcetostring((DCEnode*)dapconstraint));
54#endif
55    return ncstat;
56}
57
58/* Worksheet
59
60mg.st = md.st * ms.st
61mg.f  = md.f+(ms.f*md.st)
62mg.l  = ((ms.l-1) / ms.st) * mg.st + 1
63mg.p  = mg.f + mg.l
64mg.c  = mg.l / mg.st
65
660000000000111111111122222222223
670123456789012345678901234567890
68          xxxxxx
69                xxxxxx
70 0  1  2  3  4  5  6  7  8        md=(st=3 f=1 l=25 p=26)
71          0     1     2           ms=(st=2 f=3 l=5  p=8 )
72                                  ----------------------------
73                                  mg=(st=6 f=10 p=23 l=13)
74c = 4 / 2 = 2
75l = 2 * 6 + 1 = 13
76
770000000000111111
780123456789012345
79 0 1 2 3 4                md=(st=2 f=1 l=9 p=10)
80     0 1 2                ms=(st=1 f=2 l=3 p=5)
81                          ----------------------------
82                          mg=(st=2 f=5 p=10 l=5 )
83c = 2/1 = 2
84l = 2 * 2 + 1 = 13
85
860000000000111111111
870123456789012345678
88 0 1 2 3 4 5 6 7 8        md=(st=2 f=1 l=17 p=18)
89       0   1   2          ms=(st=2 f=3 l=5 p=8)
90                          ----------------------------
91                          mg=(st=4 f=7 p=16 l=9 )
92c = 4/2 = 2
93l = 2 * 4 + 1 = 9
94
950000000000111111111
960123456789012345678
97 0 1 2 3 4                md=(st=2 f=1 l=9 p=10)
98 0 1 2 3 4                ms=(st=1 f=0 l=5 p=5)
99                          ----------------------------
100                          mg=(st=2 f=1 p=10 l=9 )
101c = 4/1 = 4
102l = 4 * 2 + 1 = 9
103
10400000
10501234
10601                        md=(st=1 f=0 l=2 p=2)
1070                         ms=(st=1 f=0 l=1 p=1)
108                          ----------------------------
109                          mg=(st=1 f=0 p=1 l=1 )
110c = 0/1 = 0
111l = 0 * 1 + 1 = 1
112
113000000000011
114012345678901
115012                       md=(st=1 f=0 l=3 p=3)
116012                       ms=(st=1 f=0 l=3 p=2)
117                          ----------------------------
118                          mg=(st=1 f=0 p=3 l=3 )
119c = 2/1 = 2
120l = 2 * 1 + 1 = 3
121
122*/
123
124/* Merge slice src into slice dst; dst != src */
125
126int
127dceslicemerge(DCEslice* dst, DCEslice* src)
128{
129    int err = NC_NOERR;
130    DCEslice tmp;
131
132    tmp.node.sort = CES_SLICE;
133    tmp.stride    = (dst->stride * src->stride);
134    tmp.first     = (dst->first+((src->first)*(dst->stride)));
135    tmp.length    = (((src->length - 1) / src->stride) * tmp.stride) + 1;
136    tmp.stop      = tmp.first + tmp.length;
137    tmp.count     = tmp.length / tmp.stride;
138    /* use max declsize */
139    if(dst->declsize > src->declsize) {
140        tmp.declsize  = dst->declsize;
141    } else {
142        tmp.declsize  = src->declsize;
143    }
144    if(tmp.length % tmp.stride != 0) tmp.count++;
145    if(tmp.first >= dst->stop || tmp.stop > dst->stop)
146        err = NC_EINVALCOORDS;
147    else
148        *dst = tmp;
149    return err;
150}
151
152
153/*
154Given two projection lists, merge
155src into dst taking
156overlapping projections into acct.
157*/
158int
159dcemergeprojectionlists(NClist* dst, NClist* src)
160{
161    int i;
162    NClist* cat = nclistnew();
163    int ncstat = NC_NOERR;
164
165#ifdef DEBUG
166fprintf(stderr,"dapmergeprojection: dst = %s\n",dcetostring((DCEnode*)dst));
167fprintf(stderr,"dapmergeprojection: src = %s\n",dcetostring((DCEnode*)src));
168#endif
169
170    /* get dst concat clone(src) */
171    nclistsetalloc(cat,nclistlength(dst)+nclistlength(src));
172    for(i=0;i<nclistlength(dst);i++) {
173        DCEprojection* p = (DCEprojection*)nclistget(dst,i);
174        nclistpush(cat,(ncelem)p);
175    }   
176    for(i=0;i<nclistlength(src);i++) {
177        DCEprojection* p = (DCEprojection*)nclistget(src,i);
178        nclistpush(cat,(ncelem)dceclone((DCEnode*)p));
179    }   
180
181    nclistclear(dst);
182
183    /* Repeatedly pull elements from the concat,
184       merge with all duplicates, and stick into
185       the dst
186    */
187    while(nclistlength(cat) > 0) {
188        DCEprojection* target = (DCEprojection*)nclistremove(cat,0);
189        if(target == NULL) continue;
190        if(target->discrim != CES_VAR) continue;
191        for(i=0;i<nclistlength(cat);i++) {
192            DCEprojection* p2 = (DCEprojection*)nclistget(cat,i);
193            if(p2 == NULL) continue;
194            if(p2->discrim != CES_VAR) continue;
195            if(dcesamepath(target->var->segments,
196                           p2->var->segments)!=0) continue;
197            /* This entry matches our current target; merge  */
198            ncstat = dcemergeprojections(target,p2);
199            /* null out this merged entry and release it */
200            nclistset(cat,i,(ncelem)NULL);         
201            dcefree((DCEnode*)p2);         
202        }                   
203        /* Capture the clone */
204        nclistpush(dst,(ncelem)target);
205    }       
206    nclistfree(cat);
207    return ncstat;
208}
209
210/* Modify merged projection to include "addition" projection */
211int
212dcemergeprojections(DCEprojection* merged, DCEprojection* addition)
213{
214    int ncstat = NC_NOERR;
215    int i,j;
216
217    ASSERT((merged->discrim == CES_VAR && addition->discrim == CES_VAR));
218    ASSERT((nclistlength(merged->var->segments) == nclistlength(addition->var->segments)));   
219    for(i=0;i<nclistlength(merged->var->segments);i++) {
220        DCEsegment* mergedseg = (DCEsegment*)nclistget(merged->var->segments,i);
221        DCEsegment* addedseg = (DCEsegment*)nclistget(addition->var->segments,i);
222        /* If one segment has larger rank, then copy the extra slices unchanged */
223        for(j=0;j<addedseg->rank;j++) {
224            if(j < mergedseg->rank)
225                dceslicemerge(mergedseg->slices+j,addedseg->slices+j);
226            else
227                mergedseg->slices[j] = addedseg->slices[j];
228        }
229        if(addedseg->rank > mergedseg->rank)
230            mergedseg->rank = addedseg->rank;
231    }
232    return ncstat;
233}
234
235/* Convert a DCEprojection instance into a string
236   that can be used with the url
237*/
238
239char*
240buildprojectionstring(NClist* projections)
241{
242    char* pstring;
243    NCbytes* buf = ncbytesnew();
244    dcelisttobuffer(projections,buf,",");
245    pstring = ncbytesdup(buf);
246    ncbytesfree(buf);
247    return pstring;
248}
249
250char*
251buildselectionstring(NClist* selections)
252{
253    NCbytes* buf = ncbytesnew();
254    char* sstring;
255    dcelisttobuffer(selections,buf,",");
256    sstring = ncbytesdup(buf);
257    ncbytesfree(buf);
258    return sstring;
259}
260
261char*
262buildconstraintstring(DCEconstraint* constraints)
263{
264    NCbytes* buf = ncbytesnew();
265    char* result = NULL;
266    dcetobuffer((DCEnode*)constraints,buf);
267    result = ncbytesdup(buf);
268    ncbytesfree(buf);
269    return result;
270}
271
272DCEnode*
273dceclone(DCEnode* node)
274{
275    DCEnode* result = NULL;
276
277    result = (DCEnode*)dcecreate(node->sort);
278    if(result == NULL) goto done;
279
280    switch (node->sort) {
281
282    case CES_SLICE: {
283        DCEslice* clone = (DCEslice*)result;
284        DCEslice* orig = (DCEslice*)node;
285        *clone = *orig;
286    } break;
287
288    case CES_SEGMENT: {
289        DCEsegment* clone = (DCEsegment*)result;
290        DCEsegment* orig = (DCEsegment*)node;
291        *clone = *orig; 
292        clone->name = nulldup(orig->name);
293        if(orig->rank > 0)
294            memcpy(clone->slices,orig->slices,orig->rank*sizeof(DCEslice));
295    } break;
296
297    case CES_VAR: {
298        DCEvar* clone = (DCEvar*)result;
299        DCEvar* orig = (DCEvar*)node;
300        *clone = *orig;
301        clone->segments = dceclonelist(clone->segments);
302    } break;
303
304    case CES_FCN: {
305        DCEfcn* clone = (DCEfcn*)result;
306        DCEfcn* orig = (DCEfcn*)node;
307        *clone = *orig;
308        clone->name = nulldup(orig->name);
309        clone->args = dceclonelist(orig->args);
310    } break;
311
312    case CES_CONST: {
313        DCEconstant* clone = (DCEconstant*)result;
314        DCEconstant* orig = (DCEconstant*)node;
315        *clone = *orig;
316        if(clone->discrim ==  CES_STR)
317            clone->text = nulldup(clone->text);
318    } break;
319
320    case CES_VALUE: {
321        DCEvalue* clone = (DCEvalue*)result;
322        DCEvalue* orig = (DCEvalue*)node;
323        *clone = *orig;
324        switch (clone->discrim) {
325        case CES_CONST:
326            clone->constant = (DCEconstant*)dceclone((DCEnode*)orig->constant); break;
327        case CES_VAR:
328            clone->var = (DCEvar*)dceclone((DCEnode*)orig->var); break;
329        case CES_FCN:
330            clone->fcn = (DCEfcn*)dceclone((DCEnode*)orig->fcn); break;
331        default: assert(0);
332        }
333    } break;
334
335    case CES_PROJECT: {
336        DCEprojection* clone = (DCEprojection*)result;
337        DCEprojection* orig = (DCEprojection*)node;
338        *clone = *orig; 
339        switch (orig->discrim) {
340        case CES_VAR:
341            clone->var = (DCEvar*)dceclone((DCEnode*)orig->var); break;
342        case CES_FCN:
343            clone->fcn = (DCEfcn*)dceclone((DCEnode*)orig->fcn); break;
344        default: assert(0);
345        }
346    } break;
347
348    case CES_SELECT: {
349        DCEselection* clone = (DCEselection*)result;
350        DCEselection* orig = (DCEselection*)node;
351        *clone = *orig; 
352        clone->lhs = (DCEvalue*)dceclone((DCEnode*)orig->lhs);
353        clone->rhs = dceclonelist(orig->rhs);
354    } break;
355
356    case CES_CONSTRAINT: {
357        DCEconstraint* clone = (DCEconstraint*)result;
358        DCEconstraint* orig = (DCEconstraint*)node;
359        *clone = *orig; 
360        clone->projections = dceclonelist(orig->projections);   
361        clone->selections = dceclonelist(orig->selections);
362    } break;
363
364    default:
365        assert(0);
366    }
367
368done:
369    return result;
370}
371
372NClist*
373dceclonelist(NClist* list)
374{
375    int i;
376    NClist* clone;
377    if(list == NULL) return NULL;
378    clone = nclistnew();
379    for(i=0;i<nclistlength(list);i++) {
380        DCEnode* node = (DCEnode*)nclistget(list,i);
381        DCEnode* newnode = dceclone((DCEnode*)node);
382        nclistpush(clone,(ncelem)newnode);
383    }
384    return clone;
385}
386
387void
388dcefree(DCEnode* node)
389{
390    if(node == NULL) return;
391
392    switch (node->sort) {
393
394    case CES_VAR: {
395        DCEvar* target = (DCEvar*)node;
396        dcefreelist(target->segments); 
397    } break;
398
399    case CES_FCN: {
400        DCEfcn* target = (DCEfcn*)node;
401        dcefreelist(target->args);     
402        nullfree(target->name);
403    } break;
404
405    case CES_CONST: {
406        DCEconstant* target = (DCEconstant*)node;
407        if(target->discrim == CES_STR)
408            nullfree(target->text);
409    } break;
410
411    case CES_VALUE: {
412        DCEvalue* target = (DCEvalue*)node;
413        switch(target->discrim) {
414        case CES_CONST: dcefree((DCEnode*)target->constant); break;   
415        case CES_VAR: dcefree((DCEnode*)target->var); break;   
416        case CES_FCN: dcefree((DCEnode*)target->fcn); break;   
417        default: assert(0);
418        }
419    } break;
420
421    case CES_PROJECT: {
422        DCEprojection* target = (DCEprojection*)node;
423        switch (target->discrim) {
424        case CES_VAR: dcefree((DCEnode*)target->var); break;
425        case CES_FCN: dcefree((DCEnode*)target->fcn); break;
426        default: assert(0);
427        }
428    } break;
429
430    case CES_SELECT: {
431        DCEselection* target = (DCEselection*)node;
432        dcefreelist(target->rhs);
433        dcefree((DCEnode*)target->lhs);
434    } break;
435
436    case CES_CONSTRAINT: {
437        DCEconstraint* target = (DCEconstraint*)node;
438        dcefreelist(target->projections);
439        dcefreelist(target->selections);
440    } break;
441
442    case CES_SEGMENT: {
443        DCEsegment* target = (DCEsegment*)node;
444        target->rank = 0;
445        nullfree(target->name);
446    } break;
447
448    case CES_SLICE: {
449    } break;
450
451    default:
452        assert(0);
453    }
454
455    /* final action */
456    free(node);
457}
458
459void
460dcefreelist(NClist* list)
461{
462    int i;
463    if(list == NULL) return;
464    for(i=0;i<nclistlength(list);i++) {
465        DCEnode* node = (DCEnode*)nclistget(list,i);
466        dcefree((DCEnode*)node);
467    }
468    nclistfree(list);
469}
470
471char*
472dcetostring(DCEnode* node)
473{
474    char* s;
475    NCbytes* buf = ncbytesnew();
476    dcetobuffer(node,buf);
477    s = ncbytesextract(buf);
478    ncbytesfree(buf);
479    return s;
480}
481
482/* For debugging */
483#ifdef DEBUG
484static char*
485dimdecl(size_t declsize)
486{
487    static char tag[16];
488    tag[0] = '\0';
489    if(dceverbose) 
490        snprintf(tag,sizeof(tag),"/%lu",(unsigned long)declsize);
491    return tag;
492}
493#else
494static char*
495dimdecl(size_t declsize)
496{
497    return "";
498}
499#endif
500
501void
502dcetobuffer(DCEnode* node, NCbytes* buf)
503{
504    int i;
505    char tmp[1024];
506
507    if(buf == NULL) return;
508    if(node == NULL) {ncbytescat(buf,"<null>"); return;}
509
510    switch (node->sort) {
511
512    case CES_SLICE: {
513            DCEslice* slice = (DCEslice*)node;
514            size_t last = (slice->first+slice->length)-1;
515            if(slice->count == 1) {
516                snprintf(tmp,sizeof(tmp),"[%lu%s]",
517                    (unsigned long)slice->first,dimdecl(slice->declsize));
518            } else if(slice->stride == 1) {
519                snprintf(tmp,sizeof(tmp),"[%lu:%lu%s]",
520                    (unsigned long)slice->first,
521                    (unsigned long)last,
522                    dimdecl(slice->declsize));
523            } else {
524                snprintf(tmp,sizeof(tmp),"[%lu:%lu:%lu%s]",
525                    (unsigned long)slice->first,
526                    (unsigned long)slice->stride,
527                    (unsigned long)last,
528                    dimdecl(slice->declsize));
529            }
530            ncbytescat(buf,tmp);
531    } break;
532
533    case CES_SEGMENT: {
534        DCEsegment* segment = (DCEsegment*)node;
535        int rank = segment->rank;
536        char* name = (segment->name?segment->name:"<unknown>");
537        name = nulldup(name);
538        ncbytescat(buf,name);
539        nullfree(name);
540        if(dceverbose && dceiswholesegment(segment))
541            ncbytescat(buf,"*");
542        if(dceverbose || !dceiswholesegment(segment)) {
543            for(i=0;i<rank;i++) {
544                DCEslice* slice = segment->slices+i;
545                dcetobuffer((DCEnode*)slice,buf);
546            }
547        }
548    } break;
549
550    case CES_VAR: {
551        DCEvar* var = (DCEvar*)node;
552        dcelisttobuffer(var->segments,buf,".");
553    } break;
554
555    case CES_FCN: {
556        DCEfcn* fcn = (DCEfcn*)node;
557        ncbytescat(buf,fcn->name);
558        ncbytescat(buf,"(");
559        dcelisttobuffer(fcn->args,buf,",");
560        ncbytescat(buf,")");
561    } break;
562
563    case CES_CONST: {
564        DCEconstant* value = (DCEconstant*)node;
565        switch (value->discrim) {
566        case CES_STR:
567            ncbytescat(buf,value->text);
568            break;             
569        case CES_INT:
570            snprintf(tmp,sizeof(tmp),"%lld",value->intvalue);
571            ncbytescat(buf,tmp);
572        break;
573        case CES_FLOAT:
574            snprintf(tmp,sizeof(tmp),"%g",value->floatvalue);
575            ncbytescat(buf,tmp);
576            break;
577        default: assert(0);
578        }
579    } break;
580
581    case CES_VALUE: {
582        DCEvalue* value = (DCEvalue*)node;
583        switch (value->discrim) {
584        case CES_CONST:
585            dcetobuffer((DCEnode*)value->constant,buf);
586            break;             
587        case CES_VAR:
588            dcetobuffer((DCEnode*)value->var,buf);
589            break;
590        case CES_FCN:
591            dcetobuffer((DCEnode*)value->fcn,buf);
592            break;
593        default: assert(0);
594        }
595    } break;
596
597    case CES_PROJECT: {
598        DCEprojection* target = (DCEprojection*)node;
599        switch (target->discrim) {
600        case CES_VAR:
601            dcetobuffer((DCEnode*)target->var,buf);
602            break;
603        case CES_FCN: dcetobuffer((DCEnode*)target->fcn,buf); break;
604        default: assert(0);
605        }
606    } break;
607
608    case CES_SELECT: {
609        DCEselection* sel = (DCEselection*)node;
610        dcetobuffer((DCEnode*)sel->lhs,buf);
611        if(sel->operator == CES_NIL) break;
612        ncbytescat(buf,opstrings[(int)sel->operator]);
613        if(nclistlength(sel->rhs) > 1)
614            ncbytescat(buf,"{");
615        dcelisttobuffer(sel->rhs,buf,",");
616        if(nclistlength(sel->rhs) > 1)
617            ncbytescat(buf,"}");
618    } break;
619
620    case CES_CONSTRAINT: {
621        DCEconstraint* con = (DCEconstraint*)node;
622        if(con->projections != NULL && nclistlength(con->projections) > 0) {
623            dcelisttobuffer(con->projections,buf,",");
624        }
625        if(con->selections != NULL && nclistlength(con->selections) > 0) {
626            ncbytescat(buf,"&"); /* because & is really a prefix */
627            dcelisttobuffer(con->selections,buf,"&");
628        }
629    } break;
630
631    case CES_NIL: {
632        ncbytescat(buf,"<nil>");
633    } break;
634
635    default:
636        assert(0);
637    }
638}
639
640char*
641dcelisttostring(NClist* list, char* sep)
642{
643    char* s;
644    NCbytes* buf = ncbytesnew();
645    dcelisttobuffer(list,buf,sep);
646    s = ncbytesextract(buf);
647    ncbytesfree(buf);
648    return s;
649}
650
651void
652dcelisttobuffer(NClist* list, NCbytes* buf, char* sep)
653{
654    int i;
655    if(list == NULL || buf == NULL) return;
656    if(sep == NULL) sep = ",";
657    for(i=0;i<nclistlength(list);i++) {
658        DCEnode* node = (DCEnode*)nclistget(list,i);
659        if(node == NULL) continue;
660        if(i>0) ncbytescat(buf,sep);
661        dcetobuffer((DCEnode*)node,buf);
662    }
663}
664
665/* Collect all nodes within a specified constraint tree */
666/* Caller frees result */
667NClist*
668dceallnodes(DCEnode* node, CEsort which)
669{
670    NClist* allnodes = nclistnew();
671    ceallnodesr(node,allnodes,which);
672    return allnodes;
673}
674
675static void
676ceallnodesr(DCEnode* node, NClist* allnodes, CEsort which)
677{
678    int i;
679    if(node == NULL) return;
680    if(nclistcontains(allnodes,(ncelem)node)) return;
681    if(which == CES_NIL || node->sort == which)
682        nclistpush(allnodes,(ncelem)node);
683    switch(node->sort) {
684    case CES_FCN: {
685        DCEfcn* fcn = (DCEfcn*)node;
686        for(i=0;i<nclistlength(fcn->args);i++) {
687            ceallnodesr((DCEnode*)nclistget(fcn->args,i),allnodes,which);
688        }
689    } break;
690    case CES_VAR: {
691        DCEvar* var = (DCEvar*)node;
692        for(i=0;i<nclistlength(var->segments);i++) {
693            ceallnodesr((DCEnode*)nclistget(var->segments,i),allnodes,which);
694        }
695    } break;
696    case CES_VALUE: {
697        DCEvalue* value = (DCEvalue*)node;
698        if(value->discrim == CES_VAR)
699            ceallnodesr((DCEnode*)value->var,allnodes,which);
700        else if(value->discrim == CES_FCN)
701            ceallnodesr((DCEnode*)value->fcn,allnodes,which);
702        else
703            ceallnodesr((DCEnode*)value->constant,allnodes,which);
704    } break;
705    case CES_SELECT: {
706        DCEselection* selection = (DCEselection*)node;
707        ceallnodesr((DCEnode*)selection->lhs,allnodes,which);
708        for(i=0;i<nclistlength(selection->rhs);i++)
709            ceallnodesr((DCEnode*)nclistget(selection->rhs,i),allnodes,which);
710    } break;
711    case CES_PROJECT: {
712        DCEprojection* projection = (DCEprojection*)node;
713        if(projection->discrim == CES_VAR)
714            ceallnodesr((DCEnode*)projection->var,allnodes,which);
715        else
716            ceallnodesr((DCEnode*)projection->fcn,allnodes,which);
717    } break;
718    case CES_CONSTRAINT: {
719        DCEconstraint* constraint = (DCEconstraint*)node;
720        for(i=0;i<nclistlength(constraint->projections);i++)
721            ceallnodesr((DCEnode*)nclistget(constraint->projections,i),allnodes,which);
722        for(i=0;i<nclistlength(constraint->selections);i++)
723            ceallnodesr((DCEnode*)nclistget(constraint->selections,i),allnodes,which);
724    } break;
725
726    /* All others have no subnodes */
727    default:
728        break;
729    }
730}
731
732DCEnode*
733dcecreate(CEsort sort)
734{
735    DCEnode* node = NULL;
736
737    switch (sort) {
738
739    case CES_SLICE: {
740        DCEslice* target = (DCEslice*)calloc(1,sizeof(DCEslice));
741        if(target == NULL) return NULL;
742        node = (DCEnode*)target;
743    } break;
744
745    case CES_SEGMENT: {
746        int i;
747        DCEsegment* target = (DCEsegment*)calloc(1,sizeof(DCEsegment));
748        if(target == NULL) return NULL;
749        /* Initialize the sort of the slices */
750        for(i=0;i<NC_MAX_VAR_DIMS;i++)
751            target->slices[i].node.sort = CES_SLICE;           
752        node = (DCEnode*)target;
753    } break;
754
755    case CES_CONST: {
756        DCEconstant* target = (DCEconstant*)calloc(1,sizeof(DCEconstant));
757        if(target == NULL) return NULL;
758        node = (DCEnode*)target;
759        target->discrim = CES_NIL;
760    } break;
761
762    case CES_VALUE: {
763        DCEvalue* target = (DCEvalue*)calloc(1,sizeof(DCEvalue));
764        if(target == NULL) return NULL;
765        node = (DCEnode*)target;
766        target->discrim = CES_NIL;
767    } break;
768
769    case CES_VAR: {
770        DCEvar* target = (DCEvar*)calloc(1,sizeof(DCEvar));
771        if(target == NULL) return NULL;
772        node = (DCEnode*)target;
773    } break;
774
775    case CES_FCN: {
776        DCEfcn* target = (DCEfcn*)calloc(1,sizeof(DCEfcn));
777        if(target == NULL) return NULL;
778        node = (DCEnode*)target;
779    } break;
780
781    case CES_PROJECT: {
782        DCEprojection* target = (DCEprojection*)calloc(1,sizeof(DCEprojection));
783        if(target == NULL) return NULL;
784        node = (DCEnode*)target;
785    } break;
786
787    case CES_SELECT: {
788        DCEselection* target = (DCEselection*)calloc(1,sizeof(DCEselection));
789        if(target == NULL) return NULL;
790        node = (DCEnode*)target;
791        target->operator = CEO_NIL;
792    } break;
793
794    case CES_CONSTRAINT: {
795        DCEconstraint* target = (DCEconstraint*)calloc(1,sizeof(DCEconstraint));
796        if(target == NULL) return NULL;
797        node = (DCEnode*)target;
798    } break;
799
800    default:
801        assert(0);
802    }
803
804    /* final action */
805    node->sort = sort;
806    return node;
807}
808
809int
810dceiswholeslice(DCEslice* slice)
811{
812    if(slice->first != 0
813       || slice->stride != 1
814       || slice->stop != slice->declsize) return 0;
815    return 1;
816}
817
818int
819dceiswholesegment(DCEsegment* seg)
820{
821    int i,whole;
822   
823    if(!seg->slicesdefined) return 0; /* actually, we don't know */
824    whole = 1; /* assume so */
825    for(i=0;i<seg->rank;i++) {
826        if(!dceiswholeslice(&seg->slices[i])) {whole = 0; break;}       
827    }
828    return whole;
829}
830
831void
832dcemakewholeslice(DCEslice* slice, size_t declsize)
833{
834    slice->first = 0;
835    slice->stride = 1;
836    slice->length = declsize;
837    slice->stop = declsize;
838    slice->declsize = declsize;
839    slice->count = declsize;
840}
841
842/* Remove slicing from terminal segment of p */
843void
844dcemakewholeprojection(DCEprojection* p)
845{
846    /* Remove the slicing (if any) from the last segment */
847    if(p->discrim == CES_VAR && p->var != NULL && p->var->segments != NULL) {
848        int lastindex = nclistlength(p->var->segments) - 1;
849        DCEsegment* lastseg = (DCEsegment*)nclistget(p->var->segments,lastindex);
850        lastseg->rank = 0;
851    }   
852}
853
854int
855dcesamepath(NClist* list1, NClist* list2)
856{
857    int i;
858    int len = nclistlength(list1);
859    if(len != nclistlength(list2)) return 0;
860    for(i=0;i<len;i++) {
861        DCEsegment* s1 = (DCEsegment*)nclistget(list1,i);
862        DCEsegment* s2 = (DCEsegment*)nclistget(list2,i);
863        if(strcmp(s1->name,s2->name) != 0) return 0;
864    }
865    return 1;
866}
Note: See TracBrowser for help on using the repository browser.