/* - range - supply cvec for a range, including legality check ^ static struct cvec *range(struct vars *, celt, celt, int); */ static struct cvec * range( struct vars *v, /* context */ celt a, /* range start */ celt b, /* range end, might equal a */ int cases) /* case-independent? */ { int nchrs; struct cvec *cv; celt c, lc, uc, tc; if (a != b && !before(a, b)) { ERR(REG_ERANGE); return NULL; } if (!cases) { /* easy version */ cv = getcvec(v, 0, 1); NOERRN(); addrange(cv, a, b); return cv; } /* * When case-independent, it's hard to decide when cvec ranges are usable, * so for now at least, we won't try. We allocate enough space for two * case variants plus a little extra for the two title case variants. */ nchrs = (b - a + 1)*2 + 4; cv = getcvec(v, nchrs, 0); NOERRN(); for (c=a; c<=b; c++) { addchr(cv, c); lc = Tcl_UniCharToLower((chr)c); uc = Tcl_UniCharToUpper((chr)c); tc = Tcl_UniCharToTitle((chr)c); if (c != lc) { addchr(cv, lc); } if (c != uc) { addchr(cv, uc); } if (c != tc && tc != uc) { addchr(cv, tc); } } return cv; }
/* * range - supply cvec for a range, including legality check */ static struct cvec * range(struct vars * v, /* context */ celt a, /* range start */ celt b, /* range end, might equal a */ int cases) /* case-independent? */ { int nchrs; struct cvec *cv; celt c, cc; if (a != b && !before(a, b)) { ERR(REG_ERANGE); return NULL; } if (!cases) { /* easy version */ cv = getcvec(v, 0, 1); NOERRN(); addrange(cv, a, b); return cv; } /* * When case-independent, it's hard to decide when cvec ranges are usable, * so for now at least, we won't try. We use a range for the originally * specified chrs and then add on any case-equivalents that are outside * that range as individual chrs. * * To ensure sane behavior if someone specifies a very large range, limit * the allocation size to 100000 chrs (arbitrary) and check for overrun * inside the loop below. */ nchrs = b - a + 1; if (nchrs <= 0 || nchrs > 100000) nchrs = 100000; cv = getcvec(v, nchrs, 1); NOERRN(); addrange(cv, a, b); for (c = a; c <= b; c++) { cc = pg_wc_tolower((chr) c); if (cc !=c && (before(cc, a) || before(b, cc))) { if (cv->nchrs >= cv->chrspace) { ERR(REG_ETOOBIG); return NULL; } addchr(cv, cc); } cc = pg_wc_toupper((chr) c); if (cc != c && (before(cc, a) || before(b, cc))) { if (cv->nchrs >= cv->chrspace) { ERR(REG_ETOOBIG); return NULL; } addchr(cv, cc); } } return cv; }