2 * re_*exec and friends - match REs
4 * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
6 * Development of this software was funded, in part, by Cray Research Inc.,
7 * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
8 * Corporation, none of whom are responsible for the results. The author
11 * Redistribution and use in source and binary forms -- with or without
12 * modification -- are permitted for any purpose, provided that
13 * redistributions in source form retain this entire copyright notice and
14 * indicate the origin and nature of any modifications.
16 * I'd appreciate being given credit for this package in the documentation
17 * of software which uses it, but that is not a requirement.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * src/backend/regex/regexec.c
38/* lazy-DFA representation */
40{
/* "pointer" to an outarc */
47 unsigned *
states;
/* pointer to bitvector */
48 unsigned hash;
/* hash of bitvector */
49 #define HASH(bv, nw) (((nw) == 1) ? *(bv) : hash(bv, nw))
50 #define HIT(h,bv,ss,nw) ((ss)->hash == (h) && ((nw) == 1 || \
51 memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
53 #define STARTER 01 /* the initial state set */
54 #define POSTSTATE 02 /* includes the goal state */
55 #define LOCKED 04 /* locked in cache */
56 #define NOPROGRESS 010 /* zero-progress state set */
57 struct arcp ins;
/* chain of inarcs pointing here */
59 struct sset **
outs;
/* outarc vector indexed by color */
66 int nssused;
/* how many entries occupied yet */
68 int ncolors;
/* length of outarc and inchain vectors */
69 int wordsper;
/* length of state-set bitvectors */
72 unsigned *
work;
/* pointer to work area within statesarea */
78 chr *
lastnopr;
/* location of last cache-flushed NOPROGRESS */
79 struct sset *
search;
/* replacement-search-pointer memory */
80 int backno;
/* if DFA for a backref, subno it refers to */
81 short backmin;
/* min repetitions for backref */
82 short backmax;
/* max repetitions for backref */
87 #define WORK 1 /* number of work bitvectors needed */
89/* setup for non-malloc allocation for small cases */
90 #define FEWSTATES 20 /* must be less than UBITS */
101 #define DOMALLOC ((struct smalldfa *)NULL) /* force malloc */
105/* internal variables, bundled for easy passing around */
117 int err;
/* error code if any (0 none) */
126 #define VISERR(vv) ((vv)->err != 0) /* have we seen an error yet? */
127 #define ISERR() VISERR(v)
128 #define VERR(vv,e) ((vv)->err = ((vv)->err ? (vv)->err : (e)))
129 #define ERR(e) VERR(v, e) /* record an error */
130 #define NOERR() {if (ISERR()) return v->err;} /* if error seen, return it */
131 #define OFF(p) ((p) - v->start)
132 #define LOFF(p) ((long)OFF(p))
137 * forward declarations
139/* === regexec.c === */
145 struct dfa *d,
struct dfa *s,
chr **coldp);
157/* === rege_dfa.c === */
161 chr *max,
chr **coldp,
int *hitstopp);
163 struct sset **lastcss,
chr **lastcp);
170 static unsigned hash(
unsigned *uv,
int n);
182 * pg_regexec - match regular expression
195 struct vars *v = &var;
208 if (re == NULL ||
string == NULL || re->re_magic !=
REMAGIC)
210 if (re->re_csize !=
sizeof(
chr))
212 if (search_start >
len)
215 /* Initialize locale-dependent support */
220 v->
g = (
struct guts *) re->re_guts;
227 if (backref && nmatch <= v->g->nsub)
229 /* need larger work area */
241 /* we can store results directly in caller's array */
243 /* ensure any extra entries in caller's array are filled with -1 */
246 /* then forget about extra entries, to avoid useless work in find() */
247 if (nmatch > v->
g->
nsub + 1)
248 nmatch = v->
g->
nsub + 1;
260 /* below this point, "goto cleanup" will behave sanely */
275 for (
i = 0;
i < n;
i++)
288 for (
i = 0;
i < n;
i++)
297 for (
i = 0;
i < n;
i++)
311 /* on success, ensure caller's match vector is filled correctly */
316 /* copy portion of match vector over from (larger) work area */
317 assert(nmatch <= v->nmatch);
322 /* don't expose possibly-partial sub-match results to caller */
366 * getsubdfa - create or re-fetch the DFA for a tree subre node
368 * We only need to create the DFA once per overall regex execution.
369 * The DFA will be freed by the cleanup step in pg_regexec().
382 /* set up additional info if this is a backref node */
395 * getladfa - create or re-fetch the DFA for a LACON subre node
397 * Same as above, but for LACONs.
410 /* a LACON can't contain a backref, so nothing else to do */
416 * find - find a match for the main NFA (no-complications case)
428 chr *open;
/* open and close of range of possible starts */
433 /* first, a shot with the search RE */
440 &cold, (
int *) NULL);
452 if (
close == NULL)
/* not found */
454 if (v->
nmatch == 0)
/* found, don't need exact location */
457 /* find starting point and match */
465 for (begin = open; begin <=
close; begin++)
467 MDEBUG((
"\nfind trying at %ld\n",
LOFF(begin)));
470 (
chr **) NULL, &hitend);
478 if (hitend && cold == NULL)
481 break;
/* NOTE BREAK OUT */
483 assert(end != NULL);
/* search RE succeeded so loop should */
486 /* and pin down details */
498 if (v->
nmatch == 1)
/* no need for submatches */
501 /* find submatches */
506 * cfind - find a match for the main NFA (with complications)
546 * cfindloop - the heart of cfind
554 chr **coldp)
/* where to put coldstart pointer */
559 chr *open;
/* open and close of range of possible starts */
567 assert(d != NULL && s != NULL);
572 /* Search with the search RE for match range at/beyond "close" */
581 break;
/* no more possible match anywhere */
585 /* Search for matches starting between "open" and "close" inclusive */
587 for (begin = open; begin <=
close; begin++)
589 MDEBUG((
"\ncfind trying at %ld\n",
LOFF(begin)));
594 /* Here we use the top node's detailed RE */
597 estop, (
chr **) NULL, &hitend);
599 end =
longest(v, d, begin, estop,
606 if (hitend && cold == NULL)
609 break;
/* no match with this begin point, try next */
611 /* Dissect the potential match to see if it really matches */
629 /* Try next longer/shorter match with same begin point */
633 break;
/* no more, so try next begin point */
639 break;
/* no more, so try next begin point */
642 }
/* end loop over endpoint positions */
643 }
/* end loop over beginning positions */
646 * If we get here, there is no possible match starting at or before
647 * "close", so consider matches beyond that. We'll do a fresh search
648 * with the search RE to find a new promising match range.
651 }
while (close < v->stop);
658 * zapallsubs - initialize all subexpression matches to "no match"
660 * Note that p[0], the overall-match location, is not touched.
668 for (
i = n - 1;
i > 0;
i--)
676 * zaptreesubs - initialize subexpressions within subtree to "no match"
687 if ((
size_t) n < v->nmatch)
699 * subset - set subexpression match data for a successful subre
710 if ((
size_t) n >= v->
nmatch)
719 * cdissect - check backrefs and determine subexpression matches
721 * cdissect recursively processes a subre tree to check matching of backrefs
722 * and/or identify submatch boundaries for capture nodes. The proposed match
723 * runs from "begin" to "end" (not including "end"), and we are basically
724 * "dissecting" it to see where the submatches are.
726 * Before calling any level of cdissect, the caller must have run the node's
727 * DFA and found that the proposed substring satisfies the DFA. (We make
728 * the caller do that because in concatenation and iteration nodes, it's
729 * much faster to check all the substrings against the child DFAs before we
732 * A side-effect of a successful match is to save match locations for
733 * capturing subexpressions in v->pmatch[]. This is a little bit tricky,
734 * so we make the following rules:
735 * 1. Before initial entry to cdissect, all match data must have been
736 * cleared (this is seen to by zapallsubs).
737 * 2. Before any recursive entry to cdissect, the match data for that
738 * subexpression tree must be guaranteed clear (see zaptreesubs).
739 * 3. When returning REG_OKAY, each level of cdissect will have saved
740 * any relevant match locations.
741 * 4. When returning REG_NOMATCH, each level of cdissect will guarantee
742 * that its subexpression match locations are again clear.
743 * 5. No guarantees are made for error cases (i.e., other result codes).
744 * 6. When a level of cdissect abandons a successful sub-match, it will
745 * clear that subtree's match locations with zaptreesubs before trying
746 * any new DFA match or cdissect call for that subtree or any subtree
747 * to its right (that is, any subtree that could have a backref into the
749 * This may seem overly complicated, but it's difficult to simplify it
750 * because of the provision that match locations must be reset before
751 * any fresh DFA match (a rule that is needed to make dfa_backref safe).
752 * That means it won't work to just reset relevant match locations at the
753 * start of each cdissect level.
755static int /* regexec return code */
758 chr *
begin,
/* beginning of relevant substring */
759 chr *
end)
/* end of same */
766 /* handy place to check for operation cancel */
768 /* ... and stack overrun */
774 case '=':
/* terminal node */
776 er =
REG_OKAY;
/* no action, parent did the work */
778 case 'b':
/* back reference */
782 case '.':
/* concatenation */
789 case '|':
/* alternation */
793 case '*':
/* iteration */
800 case '(':
/* no-op capture node */
810 * We should never have a match failure unless backrefs lurk below;
811 * otherwise, either caller failed to check the DFA, or there's some
812 * inconsistency between the DFA and the node's innards.
817 * If this node is marked as capturing, save successful match's location.
826 * ccondissect - dissect match for concatenation node
828static int /* regexec return code */
831 chr *
begin,
/* beginning of relevant substring */
832 chr *
end)
/* end of same */
853 /* pick a tentative midpoint */
854 mid =
longest(v, d, begin, end, (
int *) NULL);
858 MDEBUG((
"%d: tentative midpoint %ld\n", t->
id,
LOFF(mid)));
860 /* iterate until satisfaction or failure */
863 /* try this midpoint on for size */
864 if (
longest(v, d2, mid, end, (
int *) NULL) == end)
873 MDEBUG((
"%d: successful\n", t->
id));
876 /* Reset left's matches (right should have done so itself) */
884 /* that midpoint didn't work, find a new one */
887 /* all possibilities exhausted */
888 MDEBUG((
"%d: no midpoint\n", t->
id));
891 mid =
longest(v, d, begin, mid - 1, (
int *) NULL);
895 /* failed to find a new one */
896 MDEBUG((
"%d: failed midpoint\n", t->
id));
907 * crevcondissect - dissect match for concatenation node, shortest-first
909static int /* regexec return code */
912 chr *begin,
/* beginning of relevant substring */
913 chr *end)
/* end of same */
934 /* pick a tentative midpoint */
935 mid =
shortest(v, d, begin, begin, end, (
chr **) NULL, (
int *) NULL);
939 MDEBUG((
"%d: tentative midpoint %ld\n", t->
id,
LOFF(mid)));
941 /* iterate until satisfaction or failure */
944 /* try this midpoint on for size */
945 if (
longest(v, d2, mid, end, (
int *) NULL) == end)
954 MDEBUG((
"%d: successful\n", t->
id));
957 /* Reset left's matches (right should have done so itself) */
965 /* that midpoint didn't work, find a new one */
968 /* all possibilities exhausted */
969 MDEBUG((
"%d: no midpoint\n", t->
id));
972 mid =
shortest(v, d, begin, mid + 1, end, (
chr **) NULL, (
int *) NULL);
976 /* failed to find a new one */
977 MDEBUG((
"%d: failed midpoint\n", t->
id));
988 * cbrdissect - dissect match for backref node
990 * The backref match might already have been verified by dfa_backref(),
991 * but we don't know that for sure so must check it here.
993static int /* regexec return code */
996 chr *begin,
/* beginning of relevant substring */
997 chr *end)
/* end of same */
1011 assert((
size_t) n < v->nmatch);
1013 MDEBUG((
"%d: cbrdissect %d{%d-%d} %ld-%ld\n", t->
id, n, min, max,
1016 /* get the backreferenced string */
1017 if (v->
pmatch[n].rm_so == -1)
1022 /* special cases for zero-length strings */
1026 * matches only if target is zero length, but any number of
1027 * repetitions can be considered to be present
1029 if (begin == end && min <= max)
1031 MDEBUG((
"%d: backref matched trivially\n", t->
id));
1038 /* matches only if zero repetitions are okay */
1041 MDEBUG((
"%d: backref matched trivially\n", t->
id));
1048 * check target length to see if it could possibly be an allowed number of
1049 * repetitions of brstring
1053 if (tlen % brlen != 0)
1055 numreps = tlen / brlen;
1056 if (numreps < min || (numreps > max && max !=
DUPINF))
1059 /* okay, compare the actual string contents */
1061 while (numreps-- > 0)
1063 if ((*v->
g->compare) (brstring, p, brlen) != 0)
1068 MDEBUG((
"%d: backref matched\n", t->
id));
1073 * caltdissect - dissect match for alternation node
1075static int /* regexec return code */
1078 chr *begin,
/* beginning of relevant substring */
1079 chr *end)
/* end of same */
1087 /* there should be at least 2 alternatives */
1098 if (
longest(v, d, begin, end, (
int *) NULL) == end)
1100 MDEBUG((
"%d: caltdissect matched\n", t->
id));
1114 * citerdissect - dissect match for iteration node
1116static int /* regexec return code */
1119 chr *begin,
/* beginning of relevant substring */
1120 chr *end)
/* end of same */
1140 * For the moment, assume the minimum number of matches is 1. If zero
1141 * matches are allowed, and the target string is empty, we are allowed to
1142 * match regardless of the contents of the iter node --- but we would
1143 * prefer to match once, so that capturing parens get set. (An example of
1144 * the concern here is a pattern like "()*1円", which historically this
1145 * code has allowed to succeed.) Therefore, we deal with the zero-matches
1146 * case at the bottom, after failing to find any other way to match.
1148 min_matches = t->
min;
1149 if (min_matches <= 0)
1153 * We need workspace to track the endpoints of each sub-match. Normally
1154 * we consider only nonzero-length sub-matches, so there can be at most
1155 * end-begin of them. However, if min is larger than that, we will also
1156 * consider zero-length sub-matches in order to find enough matches.
1158 * For convenience, endpts[0] contains the "begin" pointer and we store
1159 * sub-match endpoints in endpts[1..max_matches].
1161 max_matches = end - begin;
1163 max_matches = t->
max;
1164 if (max_matches < min_matches)
1165 max_matches = min_matches;
1166 endpts = (
chr **)
MALLOC((max_matches + 1) *
sizeof(
chr *));
1179 * Our strategy is to first find a set of sub-match endpoints that are
1180 * valid according to the child node's DFA, and then recursively dissect
1181 * each sub-match to confirm validity. If any validity check fails,
1182 * backtrack that sub-match and try again. And, when we next try for a
1183 * validity check, we need not recheck any successfully verified
1184 * sub-matches that we didn't move the endpoints of. nverified remembers
1185 * how many sub-matches are currently known okay.
1188 /* initialize to consider first sub-match */
1193 /* iterate until satisfaction or failure */
1196 /* try to find an endpoint for the k'th sub-match */
1197 endpts[k] =
longest(v, d, endpts[k - 1], limit, (
int *) NULL);
1203 if (endpts[k] == NULL)
1205 /* no match possible, so see if we can shorten previous one */
1209 MDEBUG((
"%d: working endpoint %d: %ld\n",
1210 t->
id, k,
LOFF(endpts[k])));
1212 /* k'th sub-match can no longer be considered verified */
1216 if (endpts[k] != end)
1218 /* haven't reached end yet, try another iteration if allowed */
1219 if (k >= max_matches)
1221 /* must try to shorten some previous match */
1226 /* reject zero-length match unless necessary to achieve min */
1227 if (endpts[k] == endpts[k - 1] &&
1228 (k >= min_matches || min_matches - k < end - endpts[k]))
1237 * We've identified a way to divide the string into k sub-matches that
1238 * works so far as the child DFA can tell. If k is an allowed number
1239 * of matches, start the slow part: recurse to verify each sub-match.
1240 * We always have k <= max_matches, needn't check that.
1242 if (k < min_matches)
1245 MDEBUG((
"%d: verifying %d..%d\n", t->
id, nverified + 1, k));
1247 for (
i = nverified + 1;
i <= k;
i++)
1249 /* zap any match data from a non-last iteration */
1259 /* oops, something failed */
1267 MDEBUG((
"%d: successful\n", t->
id));
1272 /* i'th match failed to verify, so backtrack it */
1278 * Must consider shorter versions of the k'th sub-match. However,
1279 * we'll only ask for a zero-length match if necessary.
1283 chr *prev_end = endpts[k - 1];
1285 if (endpts[k] > prev_end)
1287 limit = endpts[k] - 1;
1288 if (limit > prev_end ||
1289 (k < min_matches && min_matches - k >= end - prev_end))
1291 /* break out of backtrack loop, continue the outer one */
1295 /* can't shorten k'th sub-match any more, consider previous one */
1300 /* all possibilities exhausted */
1304 * Now consider the possibility that we can match to a zero-length string
1305 * by using zero repetitions.
1307 if (t->
min == 0 && begin == end)
1309 MDEBUG((
"%d: allowing zero matches\n", t->
id));
1318 * creviterdissect - dissect match for iteration node, shortest-first
1320static int /* regexec return code */
1323 chr *begin,
/* beginning of relevant substring */
1324 chr *end)
/* end of same */
1344 * If zero matches are allowed, and target string is empty, just declare
1345 * victory. OTOH, if target string isn't empty, zero matches can't work
1346 * so we pretend the min is 1.
1348 min_matches = t->
min;
1349 if (min_matches <= 0)
1353 MDEBUG((
"%d: allowing zero matches\n", t->
id));
1360 * We need workspace to track the endpoints of each sub-match. Normally
1361 * we consider only nonzero-length sub-matches, so there can be at most
1362 * end-begin of them. However, if min is larger than that, we will also
1363 * consider zero-length sub-matches in order to find enough matches.
1365 * For convenience, endpts[0] contains the "begin" pointer and we store
1366 * sub-match endpoints in endpts[1..max_matches].
1368 max_matches = end - begin;
1370 max_matches = t->
max;
1371 if (max_matches < min_matches)
1372 max_matches = min_matches;
1373 endpts = (
chr **)
MALLOC((max_matches + 1) *
sizeof(
chr *));
1386 * Our strategy is to first find a set of sub-match endpoints that are
1387 * valid according to the child node's DFA, and then recursively dissect
1388 * each sub-match to confirm validity. If any validity check fails,
1389 * backtrack that sub-match and try again. And, when we next try for a
1390 * validity check, we need not recheck any successfully verified
1391 * sub-matches that we didn't move the endpoints of. nverified remembers
1392 * how many sub-matches are currently known okay.
1395 /* initialize to consider first sub-match */
1400 /* iterate until satisfaction or failure */
1403 /* disallow zero-length match unless necessary to achieve min */
1404 if (limit == endpts[k - 1] &&
1406 (k >= min_matches || min_matches - k < end - limit))
1409 /* if this is the last allowed sub-match, it must reach to the end */
1410 if (k >= max_matches)
1413 /* try to find an endpoint for the k'th sub-match */
1414 endpts[k] =
shortest(v, d, endpts[k - 1], limit, end,
1415 (
chr **) NULL, (
int *) NULL);
1421 if (endpts[k] == NULL)
1423 /* no match possible, so see if we can lengthen previous one */
1427 MDEBUG((
"%d: working endpoint %d: %ld\n",
1428 t->
id, k,
LOFF(endpts[k])));
1430 /* k'th sub-match can no longer be considered verified */
1434 if (endpts[k] != end)
1436 /* haven't reached end yet, try another iteration if allowed */
1437 if (k >= max_matches)
1439 /* must try to lengthen some previous match */
1445 limit = endpts[k - 1];
1450 * We've identified a way to divide the string into k sub-matches that
1451 * works so far as the child DFA can tell. If k is an allowed number
1452 * of matches, start the slow part: recurse to verify each sub-match.
1453 * We always have k <= max_matches, needn't check that.
1455 if (k < min_matches)
1458 MDEBUG((
"%d: verifying %d..%d\n", t->
id, nverified + 1, k));
1460 for (
i = nverified + 1;
i <= k;
i++)
1462 /* zap any match data from a non-last iteration */
1472 /* oops, something failed */
1480 MDEBUG((
"%d: successful\n", t->
id));
1485 /* i'th match failed to verify, so backtrack it */
1491 * Must consider longer versions of the k'th sub-match.
1495 if (endpts[k] < end)
1497 limit = endpts[k] + 1;
1498 /* break out of backtrack loop, continue the outer one */
1501 /* can't lengthen k'th sub-match any more, consider previous one */
1506 /* all possibilities exhausted */
static void cleanup(void)
if(TABLE==NULL||TABLE_index==NULL)
void pg_set_regex_collation(Oid collation)
static int find(struct vars *v, struct cnfa *cnfa, struct colormap *cm)
static int citerdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static void freedfa(struct dfa *d)
static chr * shortest(struct vars *v, struct dfa *d, chr *start, chr *min, chr *max, chr **coldp, int *hitstopp)
static void zapallsubs(regmatch_t *p, size_t n)
static chr * dfa_backref(struct vars *v, struct dfa *d, chr *start, chr *min, chr *max, bool shortest)
static int lacon(struct vars *v, struct cnfa *pcnfa, chr *cp, color co)
static int ccondissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static int cfind(struct vars *v, struct cnfa *cnfa, struct colormap *cm)
static int creviterdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static int cfindloop(struct vars *v, struct cnfa *cnfa, struct colormap *cm, struct dfa *d, struct dfa *s, chr **coldp)
static unsigned hash(unsigned *uv, int n)
static int cbrdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static struct dfa * getladfa(struct vars *v, int n)
static chr * lastcold(struct vars *v, struct dfa *d)
static struct dfa * getsubdfa(struct vars *v, struct subre *t)
static chr * longest(struct vars *v, struct dfa *d, chr *start, chr *stop, int *hitstopp)
static struct sset * getvacant(struct vars *v, struct dfa *d, chr *cp, chr *start)
static int crevcondissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static struct sset * miss(struct vars *v, struct dfa *d, struct sset *css, color co, chr *cp, chr *start)
static struct dfa * newdfa(struct vars *v, struct cnfa *cnfa, struct colormap *cm, struct smalldfa *sml)
static struct sset * initialize(struct vars *v, struct dfa *d, chr *start)
static int cdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static void zaptreesubs(struct vars *v, struct subre *t)
static struct sset * pickss(struct vars *v, struct dfa *d, chr *cp, chr *start)
static int caltdissect(struct vars *v, struct subre *t, chr *begin, chr *end)
static void subset(struct vars *v, struct subre *sub, chr *begin, chr *end)
int pg_regexec(regex_t *re, const chr *string, size_t len, size_t search_start, rm_detail_t *details, size_t nmatch, regmatch_t pmatch[], int flags)
static int matchuntil(struct vars *v, struct dfa *d, chr *probe, struct sset **lastcss, chr **lastcp)
#define STACK_TOO_DEEP(re)
unsigned statesarea[FEWSTATES *2+WORK]
struct arcp incarea[FEWSTATES *2 *FEWCOLORS]
struct sset * outsarea[FEWSTATES *2 *FEWCOLORS]
struct sset ssets[FEWSTATES *2]