/** Sort an adjacency list for a specified vertex using ecmp(). * @param u is the vertex whose adjacency list is to be sorted. */ void Graph::sortAlist(vertex u) { assert(validVertex(u)); int ep; int j, k, p, c; if (fe[u] == 0) return; // empty list int *elist = new int[n()+1]; // copy edge endpoints in adjacency list for u into an array k = 1; for (ep = fe[u]; ep != 0; ep = fe[u]) { elist[k++] = ep; fe[u] = adjLists->remove(ep,fe[u]); } k--; // put edge list in heap-order using mate(u) as key for (j = k/2; j >= 1; j--) { // do pushdown starting at position j ep = elist[j]; p = j; while (1) { c = 2*p; if (c > k) break; if (c+1 <= k && ecmp(elist[c+1]/2,elist[c]/2,u) > 0) c++; if (ecmp(elist[c]/2,ep/2,u) <= 0) break; elist[p] = elist[c]; p = c; } elist[p] = ep; } // repeatedly extract the edge with largest mate(u) from heap and // restore heap order for (j = k-1; j >= 1; j--) { ep = elist[j+1]; elist[j+1] = elist[1]; // now largest edges are in positions j+1,...,k // elist[1,...,j] forms a heap with edge having // largest mate(u) on top // pushdown from 1 in this restricted heap p = 1; while (1) { c = 2*p; if (c > j) break; if (c+1 <= j && ecmp(elist[c+1]/2,elist[c]/2,u) > 0) c++; if (ecmp(elist[c]/2,ep/2,u) <= 0) break; elist[p] = elist[c]; p = c; } elist[p] = ep; } // now elist is sorted by mate(u) // now rebuild links forming adjacency list for u fe[u] = elist[1]; for (j = 2; j <= k; j++) { fe[u] = adjLists->join(fe[u],elist[j]); } delete [] elist; }
static int _advance(char *lp, char *ep) { char *rp; char *curlp; wchar_t c, d; int n; wchar_t cl; int neg; char *bbeg; int ct; for (;;) { neg = 0; switch (*ep++) { case CCHR: if (*ep++ == *lp++) continue; return (0); case MCCHR: ep += Popwchar(ep, cl); c = cl; if ((n = Popwchar(lp, cl)) <= 0 || c != cl) return (0); lp += n; continue; case CDOT: /* * match any characters except NULL */ if ((n = Popwchar(lp, cl)) > 0) { lp += n; continue; } else if (n < 0) { lp++; continue; } else { return (0); } case CDOL: if (*lp == 0) continue; return (0); case CCEOF: loc2 = lp; return (1); case CCL: c = (unsigned char)*lp++; if (ISTHERE(c)) { ep += 32; continue; } return (0); case NMCCL: neg = 1; /* FALLTHRU */ case MCCL: rp = lp; if (cclass(ep, &rp, neg) != 1) return (0); ep += *(ep + 32) + 32; lp = rp; continue; case CBRA: braslist[*ep++] = lp; continue; case CKET: braelist[*ep++] = lp; continue; case MCCHR | RNGE: ep += Popwchar(ep, cl); c = cl; getrnge(ep); while (low--) { if ((n = Popwchar(lp, cl)) <= 0 || cl != c) return (0); lp += n; } curlp = lp; while (size--) { if ((n = Popwchar(lp, cl)) <= 0 || cl != c) break; lp += n; } if (size < 0) n = Popwchar(lp, cl); if (n == -1) return (0); lp += (n ? n : 1); ep += 2; goto mstar; case CCHR | RNGE: c = *ep++; getrnge(ep); while (low--) if (*lp++ != c) return (0); curlp = lp; while (size--) if (*lp++ != c) break; if (size < 0) lp++; ep += 2; goto star; case CDOT | RNGE: getrnge(ep); while (low--) { if ((n = Popwchar(lp, cl)) > 0) { lp += n; } else if (n < 0) { lp++; } else { return (0); } } curlp = lp; while (size--) { if ((n = Popwchar(lp, cl)) > 0) { lp += n; } else if (n < 0) { lp++; } else { break; } } if (size < 0) n = Popwchar(lp, cl); if (n > 0) { lp += n; } else { lp++; } ep += 2; goto mstar; case NMCCL | RNGE: neg = 1; /* FALLTHRU */ case MCCL | RNGE: getrnge(ep + *(ep + 32) + 32); rp = lp; while (low--) { if (cclass(ep, &rp, neg) != 1) return (0); } curlp = rp; while (size-- && (c = (cclass(ep, &rp, neg))) == 1) ; if (c == -1) return (0); lp = rp; if (size < 0) { if ((n = Popwchar(lp, cl)) == -1) return (0); lp += (n ? n : 1); } ep += *(ep + 32) + 34; goto mstar; case CCL | RNGE: getrnge(ep + 32); while (low--) { c = (unsigned char)*lp++; if (!ISTHERE(c)) return (0); } curlp = lp; while (size--) { c = (unsigned char)*lp++; if (!ISTHERE(c)) break; } if (size < 0) lp++; ep += 34; /* 32 + 2 */ goto star; case CBACK: bbeg = braslist[*ep]; ct = (int)(braelist[*ep++] - bbeg); if (ecmp(bbeg, lp, ct)) { lp += ct; continue; } return (0); case CBACK | STAR: bbeg = braslist[*ep]; ct = (int)(braelist[*ep++] - bbeg); curlp = lp; while (ecmp(bbeg, lp, ct)) lp += ct; while (lp >= curlp) { if (_advance(lp, ep)) return (1); lp -= ct; } return (0); case CDOT | STAR: curlp = lp; if (!multibyte) while (*lp++) ; else { for (;;) { n = Popwchar(lp, cl); if (n > 0) { lp += n; } else if (n < 0) { lp++; } else { lp++; break; } } } goto mstar; case CCHR | STAR: curlp = lp; while (*lp++ == *ep) ; ep++; goto star; case MCCHR | STAR: curlp = lp; ep += Popwchar(ep, cl); c = cl; while ((n = Popwchar(lp, cl)) > 0 && cl == c) lp += n; if (n == -1) return (0); lp += (n ? n : 1); goto mstar; case NMCCL | STAR: neg = 1; /* FALLTHRU */ case MCCL | STAR: curlp = rp = lp; while ((d = cclass(ep, &rp, neg)) == 1) ; if (d == -1) return (0); lp = rp; ep += *(ep + 32) + 32; goto mstar; case CCL | STAR: curlp = lp; do { c = (unsigned char)*lp++; } while (ISTHERE(c)); ep += 32; goto star; case CBRC: if (lp == start && locs == (char *)0) continue; c = (unsigned char)*lp; d = (unsigned char)*(lp-1); if ((isdigit((int)c) || uletter((int)c) || c >= 0200 && MB_CUR_MAX > 1) && !isdigit((int)d) && !uletter((int)d) && (d < 0200 || MB_CUR_MAX == 1)) continue; return (0); case CLET: d = (unsigned char)*lp; if (!isdigit((int)d) && !uletter((int)d) && (d < 0200 || MB_CUR_MAX == 1)) continue; return (0); default: return (0); } } mstar: if (multibyte) { /* MB_CUR_MAX > 1 */ if ((eucw1 != 0) || (eucw2 != 0) || (eucw3 != 0)) { /* EUC locale */ do { char *p1, *p2; lp--; p1 = lp - eucw2; p2 = lp - eucw3; /* check if previous character is from */ /* supplementary code sets 1, 2, or 3 and */ /* back up appropriate number of bytes */ if ((unsigned char)*lp >= 0200) { if (p1 >= curlp && (unsigned char)*p1 == SS2) lp = p1; else if (p2 >= curlp && (unsigned char)*p2 == SS3) lp = p2; else lp = lp - eucw1 + 1; } if (lp == locs) break; if (_advance(lp, ep)) return (1); } while (lp > curlp); return (0); } else { /* Anything else */ do { int len; char *p1, *p2; p2 = curlp; do { p1 = p2; if (isascii(*p1)) { p2 = p1 + 1; } else { len = mblen(p1, MB_CUR_MAX); if (len == -1) { len = 1; } p2 = p1 + len; } if (p2 > lp) { /* something is wrong */ return (0); } } while (p2 != lp); lp = p1; if (lp == locs) break; if (_advance(lp, ep)) return (1); } while (lp > curlp); return (0); } } star: do { if (--lp == locs) break; if (_advance(lp, ep)) return (1); } while (lp > curlp); return (0); }
static int _advance(char *lp, char *ep, step_vars_storage *vars) { char *curlp; int c; char *bbeg; char neg; int ct; int epint; /* int value of *ep */ while (1) { neg = 0; switch (*ep++) { case CCHR: if (*ep++ == *lp++) continue; return (0); case CDOT: if (*lp++) continue; return (0); case CDOL: if (*lp == 0) continue; return (0); case CCEOF: vars->loc2 = lp; return (1); case CXCL: c = (unsigned char)*lp++; if (ISTHERE(c)) { ep += 32; continue; } return (0); case NCCL: neg = 1; case CCL: c = *lp++; if (((c & 0200) == 0 && ISTHERE(c)) ^ neg) { ep += 16; continue; } return (0); case CBRA: epint = (int) *ep; vars->braslist[epint] = lp; ep++; continue; case CKET: epint = (int) *ep; vars->braelist[epint] = lp; ep++; continue; case CCHR | RNGE: c = *ep++; getrnge(ep, vars); while (vars->low--) if (*lp++ != c) return (0); curlp = lp; while (vars->size--) if (*lp++ != c) break; if (vars->size < 0) lp++; ep += 2; goto star; case CDOT | RNGE: getrnge(ep, vars); while (vars->low--) if (*lp++ == '\0') return (0); curlp = lp; while (vars->size--) if (*lp++ == '\0') break; if (vars->size < 0) lp++; ep += 2; goto star; case CXCL | RNGE: getrnge(ep + 32, vars); while (vars->low--) { c = (unsigned char)*lp++; if (!ISTHERE(c)) return (0); } curlp = lp; while (vars->size--) { c = (unsigned char)*lp++; if (!ISTHERE(c)) break; } if (vars->size < 0) lp++; ep += 34; /* 32 + 2 */ goto star; case NCCL | RNGE: neg = 1; case CCL | RNGE: getrnge(ep + 16, vars); while (vars->low--) { c = *lp++; if (((c & 0200) || !ISTHERE(c)) ^ neg) return (0); } curlp = lp; while (vars->size--) { c = *lp++; if (((c & 0200) || !ISTHERE(c)) ^ neg) break; } if (vars->size < 0) lp++; ep += 18; /* 16 + 2 */ goto star; case CBACK: epint = (int) *ep; bbeg = vars->braslist[epint]; ct = vars->braelist[epint] - bbeg; ep++; if (ecmp(bbeg, lp, ct)) { lp += ct; continue; } return (0); case CBACK | STAR: epint = (int) *ep; bbeg = vars->braslist[epint]; ct = vars->braelist[epint] - bbeg; ep++; curlp = lp; while (ecmp(bbeg, lp, ct)) lp += ct; while (lp >= curlp) { if (_advance(lp, ep, vars)) return (1); lp -= ct; } return (0); case CDOT | STAR: curlp = lp; while (*lp++); goto star; case CCHR | STAR: curlp = lp; while (*lp++ == *ep); ep++; goto star; case CXCL | STAR: curlp = lp; do { c = (unsigned char)*lp++; } while (ISTHERE(c)); ep += 32; goto star; case NCCL | STAR: neg = 1; case CCL | STAR: curlp = lp; do { c = *lp++; } while (((c & 0200) == 0 && ISTHERE(c)) ^ neg); ep += 16; goto star; star: do { if (--lp == vars->locs) break; if (_advance(lp, ep, vars)) return (1); } while (lp > curlp); return (0); } } }
int advance(uchar *alp, uchar *aep) { uchar *lp, *ep, *curlp; uchar c; uchar *bbeg; int ct; /*fprintf(stderr, "*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep); /*DEBUG*/ lp = alp; ep = aep; for (;;) switch (*ep++) { case CCHR: if (*ep++ == *lp++) continue; return(0); case CDOT: if (*lp++) continue; return(0); case CNL: case CDOL: if (*lp == 0) continue; return(0); case CEOF: loc2 = lp; return(1); case CCL: c = *lp++; if(ep[c>>3] & bittab[c & 07]) { ep += 32; continue; } return(0); case CBRA: braslist[*ep++] = lp; continue; case CKET: braelist[*ep++] = lp; continue; case CBACK: bbeg = braslist[*ep]; ct = braelist[*ep++] - bbeg; if(ecmp(bbeg, lp, ct)) { lp += ct; continue; } return(0); case CBACK|STAR: bbeg = braslist[*ep]; ct = braelist[*ep++] - bbeg; curlp = lp; while(ecmp(bbeg, lp, ct)) lp += ct; while(lp >= curlp) { if(advance(lp, ep)) return(1); lp -= ct; } return(0); case CDOT|STAR: curlp = lp; while (*lp++); goto star; case CCHR|STAR: curlp = lp; while (*lp++ == *ep); ep++; goto star; case CCL|STAR: curlp = lp; do { c = *lp++; } while(ep[c>>3] & bittab[c & 07]); ep += 32; goto star; star: if(--lp == curlp) { continue; } if(*ep == CCHR) { c = ep[1]; do { if(*lp != c) continue; if(advance(lp, ep)) return(1); } while(lp-- > curlp); return(0); } if(*ep == CBACK) { c = *(braslist[ep[1]]); do { if(*lp != c) continue; if(advance(lp, ep)) return(1); } while(lp-- > curlp); return(0); } do { if(lp == locs) break; if (advance(lp, ep)) return(1); } while (lp-- > curlp); return(0); default: fprintf(stderr, "sed: RE botch, %o\n", *--ep); exit(1); } }