Пример #1
0
/** 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;
}
Пример #2
0
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);
}
Пример #3
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);

        }
    }
}
Пример #4
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);
	}
}