コード例 #1
0
ファイル: constraints3.c プロジェクト: qingu/WRF-Libraries
/* Parse incoming url constraints, if any,
   to check for syntactic correctness */ 
NCerror
parsedapconstraints(NCDAPCOMMON* dapcomm, char* constraints,
		    DCEconstraint* dceconstraint)
{
    NCerror ncstat = NC_NOERR;
    char* errmsg;

    ASSERT(dceconstraint != NULL);
    nclistclear(dceconstraint->projections);
    nclistclear(dceconstraint->selections);

    ncstat = dapceparse(constraints,dceconstraint,&errmsg);
    if(ncstat) {
	nclog(NCLOGWARN,"DCE constraint parse failure: %s",errmsg);
	nullfree(errmsg);
        nclistclear(dceconstraint->projections);
        nclistclear(dceconstraint->selections);
    } else {
#ifdef IGNORE
	int i;
#ifdef DEBUG
	NClist* allnodes;
fprintf(stderr,"constraint: %s",dumpconstraint(dceconstraint));
#endif
        /* Go thru each node and add annotation */
        allnodes = dceallnodes((DCEnode*)dceconstraint,CES_NIL);    
	for(i=0;i<nclistlength(allnodes);i++) {
	    DCEnode* node = (DCEnode*)nclistget(allnodes,i);
	}
#endif
    }
    return ncstat;
}
コード例 #2
0
ファイル: cdf3.c プロジェクト: theoryno3/netcdf-c
/* 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;
}
コード例 #3
0
ファイル: constraints3.c プロジェクト: qingu/WRF-Libraries
/* convert all names in selections to be fully qualified */
static NCerror
qualifyselectionnames3(DCEselection* sel)
{
    NCerror ncstat = NC_NOERR;
    int i;
    NClist* segments = NULL;
    NClist* fullpath = nclistnew();

    ASSERT(sel->lhs->discrim == CES_VAR);
    collectnodepath3((CDFnode*)sel->lhs->var->annotation,fullpath,!WITHDATASET);
#ifdef DEBUG
fprintf(stderr,"qualify.sel: %s -> ",
	dumpselection(sel));
#endif
    /* Now add path nodes to create full path */
    completesegments3(fullpath,sel->lhs->var->segments);
    for(i=0;i<nclistlength(sel->rhs);i++) {
        DCEvalue* value = (DCEvalue*)nclistget(sel->rhs,i);
        if(value->discrim != CES_VAR) continue;
        nclistclear(fullpath);
        collectnodepath3((CDFnode*)value->var->annotation,fullpath,!WITHDATASET);
	completesegments3(fullpath,value->var->segments);
    }
    nclistfree(segments);
    nclistfree(fullpath);
    return THROW(ncstat);
}
コード例 #4
0
/* 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;
	}
    }
}
コード例 #5
0
ファイル: constraints3.c プロジェクト: U-238/gempak
static NCerror
fillsegmentpath(DCEprojection* p, NClist* nodes)
{
    int i;
    NCerror ncstat = NC_NOERR;
    NClist* path = nclistnew();

    ASSERT(p->discrim == CES_VAR);
    collectsegmentnames3(p->var->segments,path);
    ncstat = matchpartialname3(nodes,path,&p->var->cdfleaf);
    if(ncstat) goto done;
    /* Now complete the segment path */
    nclistclear(path);
    collectnodepath3(p->var->cdfleaf,path,!WITHDATASET);
    if(nclistlength(path) != nclistlength(p->var->segments)) {
	ncstat = NC_EINVAL;
	goto done;
    }
    for(i=0;i<nclistlength(p->var->segments);i++) {
        DCEsegment* seg = (DCEsegment*)nclistget(p->var->segments,i);
	CDFnode* node = (CDFnode*)nclistget(path,i);
	seg->cdfnode = node;
#ifdef DEBUG
fprintf(stderr,"reref: %s -> %s\n",seg->name,node->name);
#endif
    }
    
done:
    nclistfree(path);
    return ncstat;
}
コード例 #6
0
ファイル: ncdap3a.c プロジェクト: UV-CDAT/netcdf
/* Suppress variables not in usable sequences*/
NCerror
suppressunusablevars3(NCDAPCOMMON* dapcomm)
{
    int i,j;
    int found = 1;
    NClist* path = nclistnew();

    while(found) {
	found = 0;
	/* Walk backwards to aid removal semantics */
	for(i=nclistlength(dapcomm->cdf.ddsroot->tree->varnodes)-1;i>=0;i--) {
	    CDFnode* var = (CDFnode*)nclistget(dapcomm->cdf.ddsroot->tree->varnodes,i);
	    /* See if this var is under an unusable sequence */
	    nclistclear(path);
	    collectnodepath3(var,path,WITHOUTDATASET);
	    for(j=0;j<nclistlength(path);j++) {
		CDFnode* node = (CDFnode*)nclistget(path,j);
		if(node->nctype == NC_Sequence
		   && !node->usesequence) {
#ifdef DEBUG
fprintf(stderr,"suppressing var in unusable sequence: %s.%s\n",node->ncfullname,var->ncbasename);
#endif
		    found = 1;
		    break;
		}
	    }
	    if(found) break;
	}
        if(found) nclistremove(dapcomm->cdf.ddsroot->tree->varnodes,i);
    }
    nclistfree(path);
    return NC_NOERR;
}
コード例 #7
0
ファイル: constraints.c プロジェクト: gitter-badger/quinoa
/* Parse incoming url constraints, if any,
   to check for syntactic correctness */ 
NCerror
parsedapconstraints(NCDAPCOMMON* dapcomm, char* constraints,
		    DCEconstraint* dceconstraint)
{
    NCerror ncstat = NC_NOERR;
    char* errmsg;

    ASSERT(dceconstraint != NULL);
    nclistclear(dceconstraint->projections);
    nclistclear(dceconstraint->selections);

    ncstat = dapceparse(constraints,dceconstraint,&errmsg);
    if(ncstat) {
	nclog(NCLOGWARN,"DCE constraint parse failure: %s",errmsg);
	nullfree(errmsg);
        nclistclear(dceconstraint->projections);
        nclistclear(dceconstraint->selections);
    }
    return ncstat;
}
コード例 #8
0
ファイル: constraints3.c プロジェクト: U-238/gempak
/*
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;
}
コード例 #9
0
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;
}
コード例 #10
0
ファイル: dceconstraints.c プロジェクト: U-238/gempak
/* 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;
}
コード例 #11
0
ファイル: constraints3.c プロジェクト: qingu/WRF-Libraries
NCerror
fixprojections(NClist* list)
{
    int i,j,k;
    NCerror ncstat = NC_NOERR;
    NClist* tmp = nclistnew(); /* misc. uses */

#ifdef DEBUG
fprintf(stderr,"fixprojection: list = %s\n",dumpprojections(list));
#endif

    if(nclistlength(list) == 0) goto done;

    /* Step 1: remove duplicates and complain about slice mismatches */
    for(i=0;i<nclistlength(list);i++) {
	DCEprojection* p1 = (DCEprojection*)nclistget(list,i);
	if(p1 == NULL) continue;
        if(p1->discrim != CES_VAR) continue; /* dont try to unify functions */
        for(j=i;j<nclistlength(list);j++) {
	    DCEprojection* p2 = (DCEprojection*)nclistget(list,j);
	    if(p2 == NULL) continue;
	    if(p1 == p2) continue;
	    if(p2->discrim != CES_VAR) continue;
	    if(p1->var->annotation != p2->var->annotation) continue;
	    /* check for slice mismatches */
	    if(!slicematch(p1->var->segments,p2->var->segments)) {
		/* complain */
		nclog(NCLOGWARN,"Malformed projection: same variable with different slicing");
	    }
	    /* remove p32 */
	    nclistset(list,j,(ncelem)NULL);	    
	    dcefree((DCEnode*)p2);	    
	}	
    }

    /* Step 2: remove containers when a field is also present */
    for(i=0;i<nclistlength(list);i++) {
	DCEprojection* p1 = (DCEprojection*)nclistget(list,i);
	if(p1 == NULL) continue;
        if(p1->discrim != CES_VAR) continue; /* dont try to unify functions */
	if(!iscontainer((CDFnode*)p1->var->annotation))
	    continue;
        for(j=i;j<nclistlength(list);j++) {
	    DCEprojection* p2 = (DCEprojection*)nclistget(list,j);
	    if(p2 == NULL) continue;
	    if(p2->discrim != CES_VAR) continue;
	    nclistclear(tmp);
	    collectnodepath3((CDFnode*)p2->var->annotation,tmp,WITHDATASET);
	    for(k=0;k<nclistlength(tmp);k++) {
		void* candidate = (void*)nclistget(tmp,k);
	        if(candidate == p1->var->annotation) {
		    nclistset(list,i,(ncelem)NULL);	    
	            dcefree((DCEnode*)p1);
		    goto next;
		}
	    }
	}
next:   continue;
    }

    /* Step 3: expand all containers recursively down to the leaf nodes */
    for(;;) {
	nclistclear(tmp);
        for(i=0;i<nclistlength(list);i++) {
            DCEprojection* target = (DCEprojection*)nclistget(list,i);
            CDFnode* leaf;
            if(target == NULL) continue;
            if(target->discrim != CES_VAR)
                continue; /* dont try to unify functions */
            leaf = (CDFnode*)target->var->annotation;
            ASSERT(leaf != NULL);
            if(iscontainer(leaf)) {/* capture container */
		if(!nclistcontains(tmp,(ncelem)target))
                    nclistpush(tmp,(ncelem)target);
                nclistset(list,i,(ncelem)NULL);
            }
        }
	if(nclistlength(tmp) == 0) break; /*done*/
        /* Now explode the containers */
        for(i=0;i<nclistlength(tmp);i++) {
            DCEprojection* container = (DCEprojection*)nclistget(tmp,i);
	    CDFnode* leaf = (CDFnode*)container->var->annotation;
            for(j=0;i<nclistlength(leaf->subnodes);j++) {
                CDFnode* field = (CDFnode*)nclistget(leaf->subnodes,j);
		/* Convert field node to a proper constraint */
		DCEprojection* proj = projectify(field,container);
		nclistpush(list,(ncelem)proj);
	    }	    
            /* reclaim the container */
	    dcefree((DCEnode*)container);
	}
    } /*for(;;)*/

    /* remove all NULL elements */
    for(i=nclistlength(list)-1;i>=0;i--) {
        DCEprojection* target = (DCEprojection*)nclistget(list,i);
	if(target == NULL)
	    nclistremove(list,i);	
    }	

done:
#ifdef DEBUG
fprintf(stderr,"fixprojection: exploded = %s\n",dumpprojections(list));
#endif
    nclistfree(tmp);
    return ncstat;
}
コード例 #12
0
ファイル: constraints3.c プロジェクト: qingu/WRF-Libraries
static NCerror
matchpartialname3(NClist* nodes, NClist* segments, CDFnode** nodep)
{
    int i,nsegs;
    NCerror ncstat = NC_NOERR;
    DCEsegment* lastseg = NULL;
    NClist* namematches = nclistnew();
    NClist* matches = nclistnew();
    NClist* matchpath = nclistnew();

    /* Locate all nodes with the same name
       as the last element in the segment path
    */
    nsegs = nclistlength(segments);
    lastseg = (DCEsegment*)nclistget(segments,nsegs-1);
    for(i=0;i<nclistlength(nodes);i++) {
        CDFnode* node = (CDFnode*)nclistget(nodes,i);
	if(node->ocname == null)
	    continue;
	/* Path names come from oc space */
        if(strcmp(node->ocname,lastseg->name) != 0)
	    continue;
	/* Only look at selected kinds of nodes */
	if(node->nctype != NC_Sequence
               && node->nctype != NC_Structure
               && node->nctype != NC_Grid
               && node->nctype != NC_Primitive
          )
	    continue;
	nclistpush(namematches,(ncelem)node);
    }    
    if(nclistlength(namematches)==0) {
        nclog(NCLOGERR,"No match for projection name: %s",lastseg->name);
        ncstat = NC_EDDS;
	goto done;
    }

    /* Now, collect and compare paths of the matching nodes */
    for(i=0;i<nclistlength(namematches);i++) {
        CDFnode* matchnode = (CDFnode*)nclistget(namematches,i);
	nclistclear(matchpath);
	collectnodepath3(matchnode,matchpath,0);
	/* Do a suffix match */
        if(matchsuffix3(matchpath,segments)) {
	    nclistpush(matches,(ncelem)matchnode);
#ifdef DEBUG
fprintf(stderr,"matchpartialname: pathmatch: %s :: %s\n",
matchnode->ncfullname,dumpsegments(segments));
#endif
	}
    }
    /* |matches|==0 => no match; |matches|>1 => ambiguity */
    switch (nclistlength(matches)) {
    case 0:
        nclog(NCLOGERR,"No match for projection name: %s",lastseg->name);
        ncstat = NC_EDDS;
	break;
    case 1:
        if(nodep)
	    *nodep = (CDFnode*)nclistget(matches,0);
	break;
    default: {
	CDFnode* minnode = NULL;
	int minpath = 0;
	int nmin = 0; /* to catch multiple ones with same short path */
	/* ok, see if one of the matches has a path that is shorter
           then all the others */
	for(i=0;i<nclistlength(matches);i++) {
	    CDFnode* candidate = (CDFnode*)nclistget(matches,i);
	    nclistclear(matchpath);
	    collectnodepath3(candidate,matchpath,0);
	    if(minpath == 0) {
		minpath = nclistlength(matchpath);
		minnode = candidate;
	    } else if(nclistlength(matchpath) == minpath) {
	        nmin++;		
	    } else if(nclistlength(matchpath) < minpath) {
		minpath = nclistlength(matchpath);
		minnode = candidate;
		nmin = 1;
	    }
	} /*for*/
	if(minnode == NULL || nmin > 1) {	
	    nclog(NCLOGERR,"Ambiguous match for projection name: %s",
			lastseg->name);
            ncstat = NC_EDDS;
	} else if(nodep)
	    *nodep = minnode;
	} break;
    }
#ifdef DEBUG
fprintf(stderr,"matchpartialname: choice: %s %s for %s\n",
(nclistlength(matches) > 1?"":"forced"),
(*nodep)->ncfullname,dumpsegments(segments));
#endif

done:
    return THROW(ncstat);
}
コード例 #13
0
ファイル: constraints3.c プロジェクト: U-238/gempak
/* See if we can unify sets of nodes to be projected
   into larger units.
*/
static NClist*
unifyprojectionnodes3(NClist* varlist)
{
    int i;
    NClist* nodeset = nclistnew();
    NClist* containerset = nclistnew();
    NClist* containernodes = nclistnew();

    nclistsetalloc(nodeset,nclistlength(varlist));
    nclistsetalloc(containerset,nclistlength(varlist));
    /* Duplicate the varlist so we can modify it;
       simultaneously collect unique container set.
    */
    for(i=0;i<nclistlength(varlist);i++) {
	CDFnode* var = (CDFnode*)nclistget(varlist,i);
	CDFnode* container = var->container;
	nclistpush(nodeset,(ncelem)var);
	switch (container->nctype) {
	case NC_Sequence: case NC_Structure: case NC_Grid: case NC_Dataset:
	    /* add (uniquely) to container set */
	    if(!nclistcontains(containerset,(ncelem)container)) 
	        nclistpush(containerset,(ncelem)container);
	    break;
	default: break;
	}
    }

    /* Now, try to find containers whose subnodes are all in the
	varlist; repeat until no more changes */
    for(;;) {
	int changed = 0;
        for(i=0;i<nclistlength(containerset);i++) {
            int j, allfound;
            CDFnode* container = (CDFnode*)nclistget(containerset,i);
	    if(container == NULL) continue;
            nclistclear(containernodes);
            for(allfound=1,j=0;j<nclistlength(container->subnodes);j++) {
                CDFnode* subnode = (CDFnode*)nclistget(container->subnodes,j);
                if(!nclistcontains(varlist,(ncelem)subnode)) {allfound=0;break;}
                nclistpush(containernodes,(ncelem)subnode);
            }
            if(allfound) {
                nclistpush(nodeset,(ncelem)container);
                nclistset(containerset,i,(ncelem)NULL); /* remove */
                for(j=nclistlength(nodeset)-1;j>=0;j--) { /* walk backwards */
                    CDFnode* testnode = (CDFnode*)nclistget(nodeset,j);
                    if(nclistcontains(containernodes,(ncelem)testnode))
                        nclistremove(nodeset,j);/* remove */
                }
		changed = 1;
            }
        }
	if(!changed) break; /* apparently we have reached a stable situation */
    }
    /* If there is only the dataset left as a projection, then remove it */
    if(nclistlength(nodeset) == 1) {
	CDFnode* thenode = (CDFnode*)nclistget(nodeset,0);
	if(thenode->nctype == NC_Dataset) nclistclear(nodeset);
    }
    nclistfree(containerset);
    nclistfree(containernodes);
    return nodeset;
}
コード例 #14
0
ファイル: constraints3.c プロジェクト: U-238/gempak
void
restrictprojection34(NClist* varlist, NClist* projections)
{
    int i,j,len;

#ifdef DEBUG
fprintf(stderr,"restriction.before=|%s|\n",
		dumpprojections(projections));
#endif

    if(nclistlength(varlist) == 0) goto done; /* nothing to add or remove */

    /* If the projection list is empty, then add
       a projection for every variable in varlist
    */
    if(nclistlength(projections) == 0) {
        NClist* path = nclistnew();
	NClist* nodeset = NULL;
	/* Attempt to unify the vars into larger units
	   (like a complete grid) */
	nodeset = unifyprojectionnodes3(varlist);	
        for(i=0;i<nclistlength(nodeset);i++) {
	    CDFnode* var = (CDFnode*)nclistget(nodeset,i);
#ifdef DEBUG
fprintf(stderr,"restriction.candidate=|%s|\n",var->ncfullname);
#endif
	    DCEprojection* newp = (DCEprojection*)dcecreate(CES_PROJECT);

	    newp->discrim = CES_VAR;
	    newp->var = (DCEvar*)dcecreate(CES_VAR);

	    newp->var->cdfleaf = var;
	    nclistclear(path);
	    collectnodepath3(var,path,!WITHDATASET);
	    newp->var->segments = nclistnew();
	    for(j=0;j<nclistlength(path);j++) {
	        CDFnode* node = (CDFnode*)nclistget(path,j);
	        DCEsegment* newseg = (DCEsegment*)dcecreate(CES_SEGMENT);
	        newseg->name = nulldup(node->name);
	        makewholesegment3(newseg,node);/*treat as simple projections*/
	        newseg->cdfnode = node;
	        nclistpush(newp->var->segments,(ncelem)newseg);
	    }
	    nclistpush(projections,(ncelem)newp);
	}
	nclistfree(path);
	nclistfree(nodeset);
    } else {
       /* Otherwise, walk all the projections and see if they
	   intersect any of the variables. If not,
	   then remove from the projection list.
	*/
	len = nclistlength(projections);
	for(i=len-1;i>=0;i--) {/* Walk backward to facilitate removal*/
	    int intersect = 0;
	    DCEprojection* proj = (DCEprojection*)nclistget(projections,i);
	    if(proj->discrim != CES_VAR) continue;
	    for(j=0;j<nclistlength(varlist);j++) {
		CDFnode* var = (CDFnode*)nclistget(varlist,j);
		/* Note that intersection could go either way */
		if(treecontains3(var,proj->var->cdfleaf)
		   || treecontains3(proj->var->cdfleaf,var)) {intersect = 1; break;}
	    }	    
	    if(!intersect) {
		/* suppress this projection */
		DCEprojection* p = (DCEprojection*)nclistremove(projections,i);
		dcefree((DCEnode*)p);
	    }
	}
	/* Now looks for containment between projections and only keep
           the more restrictive. Is this algorithm stable against reordering?.
	*/
	for(;;) {
	    int removed = 0;
	    for(i=0;i<nclistlength(projections);i++) {
	        DCEprojection* pi = (DCEprojection*)nclistget(projections,i);
	        if(pi->discrim != CES_VAR) continue;
	        for(j=0;j<i;j++) {
	            DCEprojection* pj = (DCEprojection*)nclistget(projections,j);
	            if(pj->discrim != CES_VAR) continue;
		    if(treecontains3(pi->var->cdfleaf,pj->var->cdfleaf)) {
		        DCEprojection* p = (DCEprojection*)nclistremove(projections,j);
			dcefree((DCEnode*)p);
			removed = 1;
			break;
		    } else if(treecontains3(pj->var->cdfleaf,pi->var->cdfleaf)) {
		        DCEprojection* p = (DCEprojection*)nclistremove(projections,i);
			dcefree((DCEnode*)p);
			removed = 1;
			break;
		    }
		}
	    }
	    if(!removed) break;
	}
    }
    
done:
#ifdef DEBUG
fprintf(stderr,"restriction.after=|%s|\n",
		dumpprojections(projections));
#endif
    return;
}
コード例 #15
0
ファイル: constraints3.c プロジェクト: U-238/gempak
static NCerror
matchpartialname3(NClist* nodes, NClist* segments, CDFnode** nodep)
{
    int i,j,nsegs;
    NCerror ncstat = NC_NOERR;
    DCEsegment* lastseg = NULL;
    NClist* namematches = nclistnew();
    NClist* matches = nclistnew();
    NClist* matchpath = nclistnew();

    /* Locate all nodes with the same name
       as the last element in the path
    */
    nsegs = nclistlength(segments);
    lastseg = (DCEsegment*)nclistget(segments,nsegs-1);
    for(i=0;i<nclistlength(nodes);i++) {
        CDFnode* node = (CDFnode*)nclistget(nodes,i);
        if(node->nctype != NC_Sequence
               && node->nctype != NC_Structure
               && node->nctype != NC_Grid
               && node->nctype != NC_Primitive
        ) continue;
        if(strcmp(node->name,lastseg->name) != 0) continue;
	nclistpush(namematches,(ncelem)node);
    }    
    if(nclistlength(namematches)==0) {
        nclog(NCLOGERR,"No match for projection name: %s",lastseg->name);
        ncstat = NC_EDDS;
	goto done;
    }

    /* Now, collect and compare paths of the matching nodes */
    for(i=0;i<nclistlength(namematches);i++) {
        CDFnode* matchnode = (CDFnode*)nclistget(namematches,i);
	nclistclear(matchpath);
	collectnodepath3(matchnode,matchpath,0);
	/* Do a suffix match */
	/* starting at each node in matchpath in the path in turn,
           try to suffix match */
	for(j=0;j<nclistlength(matchpath);j++) {
	    if(nclistlength(matchpath)- j < nsegs)
	        continue; /* cannot match */
	    if(matchsuffix3(matchpath,segments,j)) {
		nclistpush(matches,(ncelem)matchnode);
		break;
	    }
	}
    }
    /* |matches|==0 => no match; |matches|>1 => ambiguity */
    switch (nclistlength(matches)) {
    case 0:
        nclog(NCLOGERR,"No match for projection name: %s",lastseg->name);
        ncstat = NC_EDDS;
	break;
    case 1:
        if(nodep)
	    *nodep = (CDFnode*)nclistget(matches,0);
	break;
    default: {
	CDFnode* minnode = NULL;
	int minpath = 0;
	int nmin = 0; /* to catch multiple ones with same short path */
	/* ok, see if one of the matches has a path that is shorter
           then all the others */
	for(i=0;i<nclistlength(matches);i++) {
	    CDFnode* candidate = (CDFnode*)nclistget(matches,i);
	    nclistclear(matchpath);
	    collectnodepath3(candidate,matchpath,0);
	    if(minpath == 0) {
		minpath = nclistlength(matchpath);
		minnode = candidate;
	    } else if(nclistlength(matchpath) == minpath) {
	        nmin++;		
	    } else if(nclistlength(matchpath) < minpath) {
		minpath = nclistlength(matchpath);
		minnode = candidate;
		nmin = 1;
	    }
	} /*for*/
	if(minnode == NULL || nmin > 1) {	
	    nclog(NCLOGERR,"Ambiguous match for projection name: %s",
			lastseg->name);
            ncstat = NC_EDDS;
	} else if(nodep)
	    *nodep = minnode;
	} break;
    }

done:
    return THROW(ncstat);
}