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); }
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); }