File Coverage

engine.c
Criterion Covered Total %
statement 2630 3065 85.8
branch 738 1144 64.5
condition n/a
subroutine n/a
pod n/a
total 3368 4209 80.0


line stmt bran cond sub pod time code
1             #include "engine.h"
2             #include "regnodes.h"
3             #include "regcomp.h"
4             #include
5             #include
6             #include
7              
8             #if PERL_API_REVISION != 5
9             #error This module is only for Perl 5
10             #else
11             #if PERL_API_VERSION == 38
12             #else
13             #if PERL_API_VERSION == 40
14             #else
15             #if PERL_API_VERSION == 42
16             #else
17             #error Unsupported PERL_API_VERSION
18             #endif
19             #endif
20             #endif
21             #endif
22              
23             #define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(a[0]))
24              
25             #define TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
26              
27             #define LETTER_COUNT ('z' - 'a' + 1)
28              
29             #define RC_BRANCH_REGNODE_SIZE 2
30             #define RC_CURLY_REGNODE_SIZE 4
31             #define INFINITE_COUNT 0x7fffffff
32              
33             #define ALNUM_BLOCK 0x0001
34             #define SPACE_BLOCK 0x0002
35             #define ALPHA_BLOCK 0x0004
36             #define NUMBER_BLOCK 0x0008
37             #define UPPER_BLOCK 0x0010
38             #define LOWER_BLOCK 0x0020
39             #define HEX_DIGIT_BLOCK 0x0040
40             #define HORIZONTAL_SPACE_BLOCK 0x0080
41             #define VERTICAL_SPACE_BLOCK 0x0100
42              
43             #define MIRROR_SHIFT 16
44             #define NOT_ALNUM_BLOCK (ALNUM_BLOCK << MIRROR_SHIFT)
45             #define NOT_SPACE_BLOCK (SPACE_BLOCK << MIRROR_SHIFT)
46             #define NOT_ALPHA_BLOCK (ALPHA_BLOCK << MIRROR_SHIFT)
47             #define NOT_NUMBER_BLOCK (NUMBER_BLOCK << MIRROR_SHIFT)
48             #define NOT_UPPER_BLOCK (UPPER_BLOCK << MIRROR_SHIFT)
49             #define NOT_LOWER_BLOCK (LOWER_BLOCK << MIRROR_SHIFT)
50             #define NOT_HEX_DIGIT_BLOCK (HEX_DIGIT_BLOCK << MIRROR_SHIFT)
51             #define NOT_HORIZONTAL_SPACE_BLOCK (HORIZONTAL_SPACE_BLOCK << MIRROR_SHIFT)
52             #define NOT_VERTICAL_SPACE_BLOCK (VERTICAL_SPACE_BLOCK << MIRROR_SHIFT)
53              
54             #define EVERY_BLOCK 0x01ff01ff
55              
56             #define FORCED_BYTE 0x01
57             #define FORCED_CHAR 0x02
58             #define FORCED_MISMATCH (FORCED_BYTE | FORCED_CHAR)
59              
60             #define MIRROR_BLOCK(b) ((((b) & 0xffff) << MIRROR_SHIFT) | ((b) >> MIRROR_SHIFT))
61              
62             /* Regexp terms are normally regnodes, except for EXACT (and EXACTF)
63             nodes, which can bundle many characters, which we have to compare
64             separately. Occasionally, we also need access to extra regexp
65             data. */
66             typedef struct
67             {
68             regexp *origin;
69             regnode *rn;
70             int spent;
71             } Arrow;
72              
73             #define ARG_LOC(p) (((struct regnode_1 *)p)->arg1.u32)
74              
75             #define GET_LITERAL(a) (((char *)((a)->rn + 1)) + (a)->spent)
76              
77             #define GET_OFFSET(rn) (NEXT_OFF(rn) ? NEXT_OFF(rn) : get_synth_offset(rn))
78              
79             typedef U32 CurlyCount;
80              
81             /* Most functions below have this signature. The first parameter is a
82             flag set after the comparison actually matched something, second
83             parameter points into the first ("left") regexp passed into
84             rc_compare, the third into the second ("right") regexp. Return
85             value is 1 for match, 0 no match, -1 error (with the lowest-level
86             failing function setting rc_error before returning it). */
87             typedef int (*FCompare)(int, Arrow *, Arrow *);
88              
89             /* Place of a char in regexp bitmap. */
90             typedef struct
91             {
92             int offs;
93             unsigned char mask;
94             } BitFlag;
95              
96             /* Set of chars and its complement formatted for convenient
97             matching. */
98             typedef struct
99             {
100             char *expl;
101             int expl_size;
102             char lookup[256];
103             char nlookup[256];
104             unsigned char bitmap[ANYOF_BITMAP_SIZE];
105             unsigned char nbitmap[ANYOF_BITMAP_SIZE];
106             } ByteClass;
107              
108             char *rc_error = 0;
109              
110             unsigned char forced_byte[ANYOF_BITMAP_SIZE];
111              
112             /* since Perl 5.18, \s matches vertical tab - see
113             * https://www.effectiveperlprogramming.com/2013/06/the-vertical-tab-is-part-of-s-in-perl-5-18/
114             * , or "Pattern White Space" in perlre */
115             static char whitespace_expl[] = { ' ', '\f', '\n', '\r', '\t', '\v' };
116              
117             static ByteClass whitespace;
118              
119             static char horizontal_whitespace_expl[] = { '\t', ' ' };
120              
121             static ByteClass horizontal_whitespace;
122              
123             static char vertical_whitespace_expl[] = { '\r', '\v', '\f', '\n' };
124              
125             static ByteClass vertical_whitespace;
126              
127             static char digit_expl[10];
128              
129             static ByteClass digit;
130              
131             static char xdigit_expl[10 + 2 * 6];
132              
133             static ByteClass xdigit;
134              
135             static char ndot_expl[] = { '\n' };
136              
137             static ByteClass ndot;
138              
139             static char alphanumeric_expl[11 + 2 * LETTER_COUNT];
140              
141             static ByteClass word_bc;
142              
143             static ByteClass alnum_bc;
144              
145             static char alpha_expl[2 * LETTER_COUNT];
146              
147             static ByteClass alpha_bc;
148              
149             static char lower_expl[LETTER_COUNT];
150              
151             static ByteClass lower_bc;
152              
153             static char upper_expl[LETTER_COUNT];
154              
155             static ByteClass upper_bc;
156              
157             /* true flags for ALNUM and its subsets, 0 otherwise */
158             static unsigned char alphanumeric_classes[REGNODE_MAX];
159              
160             /* true flags for NALNUM and its subsets, 0 otherwise */
161             static unsigned char non_alphanumeric_classes[REGNODE_MAX];
162              
163             static unsigned char word_posix_regclasses[CC_VERTSPACE_ + 1];
164              
165             static unsigned char non_word_posix_regclasses[CC_VERTSPACE_ + 1];
166              
167             static unsigned char newline_posix_regclasses[CC_VERTSPACE_ + 1];
168              
169             /* Simplified hierarchy of character classes; ignoring the difference
170             between classes (i.e. IsAlnum & IsWord), which we probably
171             shouldn't - it is a documented bug, though... */
172             static char *regclass_names[] = { "Digit", "IsAlnum", "IsSpacePerl",
173             "IsHorizSpace", "IsVertSpace",
174             "IsWord", "IsXPosixAlnum", "IsXPosixXDigit",
175             "IsAlpha", "IsXPosixAlpha",
176             "IsDigit", "IsLower", "IsUpper",
177             "IsXDigit", "SpacePerl", "VertSpace",
178             "Word", "XPosixDigit",
179             "XPosixWord", "XPosixAlpha", "XPosixAlnum",
180             "XPosixXDigit" };
181              
182             static U32 regclass_blocks[] = { NUMBER_BLOCK, ALNUM_BLOCK, SPACE_BLOCK,
183             HORIZONTAL_SPACE_BLOCK,
184             VERTICAL_SPACE_BLOCK, ALNUM_BLOCK,
185             ALNUM_BLOCK, HEX_DIGIT_BLOCK, ALPHA_BLOCK,
186             ALPHA_BLOCK, NUMBER_BLOCK, LOWER_BLOCK,
187             UPPER_BLOCK, HEX_DIGIT_BLOCK, SPACE_BLOCK,
188             VERTICAL_SPACE_BLOCK, ALNUM_BLOCK,
189             NUMBER_BLOCK, ALNUM_BLOCK, ALPHA_BLOCK,
190             ALNUM_BLOCK, HEX_DIGIT_BLOCK};
191              
192             static U32 regclass_superset[] = { NOT_SPACE_BLOCK,
193             NOT_ALPHA_BLOCK, NOT_NUMBER_BLOCK,
194             ALNUM_BLOCK, ALNUM_BLOCK,
195             ALPHA_BLOCK, ALPHA_BLOCK, HEX_DIGIT_BLOCK,
196             SPACE_BLOCK, NOT_NUMBER_BLOCK,
197             NOT_HEX_DIGIT_BLOCK };
198             static U32 regclass_subset[] = { ALNUM_BLOCK,
199             NOT_ALNUM_BLOCK, NOT_ALNUM_BLOCK,
200             ALPHA_BLOCK, NUMBER_BLOCK,
201             UPPER_BLOCK, LOWER_BLOCK, NUMBER_BLOCK,
202             HORIZONTAL_SPACE_BLOCK,
203             VERTICAL_SPACE_BLOCK, VERTICAL_SPACE_BLOCK };
204              
205             static U32 posix_regclass_blocks[CC_VERTSPACE_ + 1] = {
206             ALNUM_BLOCK /* _CC_WORDCHAR == 0 */,
207             NUMBER_BLOCK /* _CC_DIGIT == 1 */,
208             ALPHA_BLOCK /* _CC_ALPHA == 2 */,
209             LOWER_BLOCK /* _CC_LOWER == 3 */,
210             UPPER_BLOCK /* _CC_UPPER == 4 */,
211             0,
212             0,
213             ALNUM_BLOCK /* _CC_ALPHANUMERIC == 7 */,
214             0,
215             0,
216             SPACE_BLOCK /* _CC_SPACE == 10 */,
217             HORIZONTAL_SPACE_BLOCK /* _CC_BLANK == 11, and according to perlrecharclass "\p{Blank}" and "\p{HorizSpace}" are synonyms. */,
218             HEX_DIGIT_BLOCK /* _CC_XDIGIT == 12 */,
219             0,
220             0,
221             VERTICAL_SPACE_BLOCK /* _CC_VERTSPACE == 15 */,
222             };
223              
224             static unsigned char *posix_regclass_bitmaps[CC_VERTSPACE_ + 1] = {
225             word_bc.bitmap,
226             digit.bitmap,
227             alpha_bc.bitmap,
228             lower_bc.bitmap,
229             upper_bc.bitmap,
230             0,
231             0,
232             alnum_bc.bitmap,
233             0,
234             0,
235             whitespace.bitmap,
236             horizontal_whitespace.bitmap,
237             xdigit.bitmap,
238             0,
239             0,
240             vertical_whitespace.bitmap
241             };
242              
243             static unsigned char *posix_regclass_nbitmaps[CC_VERTSPACE_ + 1] = {
244             word_bc.nbitmap,
245             digit.nbitmap,
246             0,
247             0,
248             0,
249             0,
250             0,
251             alnum_bc.nbitmap,
252             0,
253             0,
254             whitespace.nbitmap,
255             horizontal_whitespace.nbitmap,
256             xdigit.nbitmap,
257             0,
258             0,
259             vertical_whitespace.nbitmap
260             };
261              
262             static unsigned char trivial_nodes[REGNODE_MAX];
263              
264             static FCompare dispatch[REGNODE_MAX][REGNODE_MAX];
265              
266             static int compare(int anchored, Arrow *a1, Arrow *a2);
267             static int compare_right_branch(int anchored, Arrow *a1, Arrow *a2);
268             static int compare_right_curly(int anchored, Arrow *a1, Arrow *a2);
269              
270 17010           static void init_bit_flag(BitFlag *bf, int c)
271             {
272             assert(c >= 0);
273              
274 17010           bf->offs = c / 8;
275 17010           bf->mask = 1 << (c % 8);
276 17010           }
277              
278 1           static void init_forced_byte()
279             {
280 1           char forced_byte_expl[] = { 'a', 'b', 'c', 'e', 'f', 'x' };
281             BitFlag bf;
282             int i;
283              
284 1           memset(forced_byte, 0, sizeof(forced_byte));
285              
286 7 100         for (i = 0; i < sizeof(forced_byte_expl); ++i)
287             {
288 6           init_bit_flag(&bf, (unsigned char)forced_byte_expl[i]);
289 6           forced_byte[bf.offs] |= bf.mask;
290             }
291              
292 9 100         for (i = 0; i < 8; ++i)
293             {
294 8           init_bit_flag(&bf, (unsigned char)('0' + i));
295 8           forced_byte[bf.offs] |= bf.mask;
296             }
297 1           }
298              
299 11           static void init_byte_class(ByteClass *bc, char *expl, int expl_size)
300             {
301             BitFlag bf;
302             int i;
303              
304 11           bc->expl = expl;
305 11           bc->expl_size = expl_size;
306              
307 11           memset(bc->lookup, 0, sizeof(bc->lookup));
308 11           memset(bc->nlookup, 1, sizeof(bc->nlookup));
309 11           memset(bc->bitmap, 0, sizeof(bc->bitmap));
310 11           memset(bc->nbitmap, 0xff, sizeof(bc->nbitmap));
311              
312 285 100         for (i = 0; i < expl_size; ++i)
313             {
314 274           bc->lookup[(unsigned char)expl[i]] = 1;
315 274           bc->nlookup[(unsigned char)expl[i]] = 0;
316              
317 274           init_bit_flag(&bf, (unsigned char)expl[i]);
318 274           bc->bitmap[bf.offs] |= bf.mask;
319 274           bc->nbitmap[bf.offs] &= ~bf.mask;
320             }
321 11           }
322              
323 76           static void init_unfolded(char *unf, char c)
324             {
325 76 50         *unf = TOLOWER(c);
    50          
326 76 50         unf[1] = ((*unf >= 'a') && (*unf <= 'z')) ? *unf - 'a' + 'A' : *unf;
    50          
327 76           }
328              
329 5135           static U32 extend_mask(U32 mask)
330             {
331             U32 prev_mask;
332             int i, j;
333              
334             /* extra cycle is inefficient but makes superset & subset
335             definitions order-independent */
336 5135           prev_mask = 0;
337 13567 100         while (mask != prev_mask)
338             {
339 8432           prev_mask = mask;
340 25296 100         for (i = 0; i < 2; ++i)
341             {
342 202368 100         for (j = 0; j < SIZEOF_ARRAY(regclass_superset); ++j)
343             {
344 185504           U32 b = regclass_superset[j];
345 185504           U32 s = regclass_subset[j];
346 185504 100         if (i)
347             {
348             U32 t;
349              
350 92752           t = MIRROR_BLOCK(b);
351 92752           b = MIRROR_BLOCK(s);
352 92752           s = t;
353             }
354              
355 185504 100         if (mask & b)
356             {
357 21807           mask |= s;
358             }
359             }
360             }
361             }
362              
363 5135           return mask;
364             }
365              
366 0           static int convert_desc_to_map(char *desc, int invert, U32 *map)
367             {
368             int i;
369 0           U32 mask = 0;
370             char *p;
371              
372             /* fprintf(stderr, "enter convert_desc_to_map(%s, %d\n", desc, invert); */
373              
374 0           p = strstr(desc, "utf8::");
375             /* make sure *(p - 1) is valid */
376 0 0         if (p == desc)
377             {
378 0           rc_error = "no inversion flag before character class description";
379 0           return -1;
380             }
381              
382 0 0         while (p)
383             {
384 0           char sign = *(p - 1);
385 0 0         for (i = 0; i < SIZEOF_ARRAY(regclass_names); ++i)
386             {
387 0 0         if (!strncmp(p + 6, regclass_names[i], strlen(regclass_names[i])))
388             {
389 0 0         if (sign == '+')
390             {
391 0 0         if (mask & (regclass_blocks[i] << MIRROR_SHIFT))
392             {
393 0 0         *map = invert ? 0 : EVERY_BLOCK;
394 0           return 1;
395             }
396              
397 0           mask |= regclass_blocks[i];
398             }
399 0 0         else if (sign == '!')
400             {
401 0 0         if (mask & regclass_blocks[i])
402             {
403 0 0         *map = invert ? 0 : EVERY_BLOCK;
404 0           return 1;
405             }
406              
407 0           mask |= (regclass_blocks[i] << MIRROR_SHIFT);
408             }
409             else
410             {
411 0           rc_error = "unknown inversion flag before character class description";
412 0           return -1;
413             }
414             }
415             }
416              
417 0           p = strstr(p + 6, "utf8::");
418             }
419              
420             /* fprintf(stderr, "parsed 0x%x\n", (unsigned)mask); */
421              
422 0 0         if ((mask & ALPHA_BLOCK) && (mask & NUMBER_BLOCK))
    0          
423             {
424 0           mask |= ALNUM_BLOCK;
425             }
426              
427 0 0         if (invert)
428             {
429 0           mask = MIRROR_BLOCK(mask);
430             }
431              
432 0 0         if ((mask & ALPHA_BLOCK) && (mask & NUMBER_BLOCK))
    0          
433             {
434 0           mask |= ALNUM_BLOCK;
435             }
436              
437 0           *map = extend_mask(mask);
438 0           return 1;
439             }
440              
441             /* invlist methods are static inside regcomp.c, so we must copy them... */
442 378           static bool *get_invlist_offset_addr(SV *invlist)
443             {
444 378           return &(((XINVLIST*) SvANY(invlist))->is_offset);
445             }
446              
447 189           static UV get_invlist_len(SV *invlist)
448             {
449 189           return (SvCUR(invlist) == 0)
450             ? 0
451 189 50         : (SvCUR(invlist) / sizeof(UV)) - *get_invlist_offset_addr(invlist);
452             }
453              
454 189           static UV *invlist_array(SV *invlist)
455             {
456 189           return ((UV *) SvPVX(invlist) + *get_invlist_offset_addr(invlist));
457             }
458              
459             /* #define DEBUG_dump_invlist */
460              
461 83           static int convert_invlist_to_map(SV *invlist, int invert, U32 *map)
462             {
463             /*
464             Not quite what's in charclass_invlists.h - we skip the header
465             as well as all ASCII values.
466             Note that changes to the arrays may require changing the switch
467             below.
468             */
469             static UV perl_space_invlist[] = { 128,
470             #include "XPerlSpace.30"
471             };
472              
473             static UV perl_space_short_invlist[] = { 256,
474             #include "XPerlSpace.30a"
475             };
476              
477             static UV horizontal_space_invlist[] = { 128, 160, 161, 5760, 5761,
478             6158, 6159, 8192, 8203, 8239, 8240, 8287, 8288, 12288, 12289 };
479              
480             static UV vertical_space_invlist[] = { 128, 133, 134, 8232, 8234 };
481              
482             static UV xposix_digit_invlist[] = { 128,
483             #include "XPosixDigit.22"
484             };
485              
486             static UV xposix_alnum_invlist[] = { 128,
487             #include "XPosixAlnum.36"
488             };
489              
490             static UV xposix_alpha_invlist[] = { 128,
491             #include "XPosixAlpha.28"
492             };
493              
494             static UV xposix_word_invlist[] = { 128,
495             #include "XPosixWord.22"
496             };
497              
498             static UV xposix_xdigit_invlist[] = { 128, 65296, 65306, 65313,
499             65319, 65345, 65351 };
500              
501             #ifdef DEBUG_dump_invlist
502             U16 i;
503             char div[3];
504             #endif
505              
506             UV *ila;
507             UV ill;
508 83           U32 mask = 0;
509              
510             #ifdef DEBUG_dump_invlist
511             fprintf(stderr, "enter convert_invlist_to_map(..., %d, ...)\n", invert);
512             #endif
513              
514 83           ill = get_invlist_len(invlist);
515             #ifdef DEBUG_dump_invlist
516             fprintf(stderr, "ill = %lu\n", ill);
517             #endif
518 83 50         ila = ill ? invlist_array(invlist) : 0;
519              
520 83           switch (ill)
521             {
522 0           case SIZEOF_ARRAY(perl_space_invlist):
523 0 0         if (!memcmp(ila, perl_space_invlist, sizeof(perl_space_invlist)))
524             {
525             #ifdef DEBUG_dump_invlist
526             fprintf(stderr, "NOT_SPACE_BLOCK\n");
527             #endif
528 0           mask = NOT_SPACE_BLOCK;
529             }
530              
531 0           break;
532              
533 0           case SIZEOF_ARRAY(perl_space_invlist) - 1:
534 0 0         if (!memcmp(ila, perl_space_invlist + 1,
535             sizeof(perl_space_invlist) - sizeof(perl_space_invlist[0])))
536             {
537             #ifdef DEBUG_dump_invlist
538             fprintf(stderr, "SPACE_BLOCK\n");
539             #endif
540 0           mask = SPACE_BLOCK;
541             }
542              
543 0           break;
544              
545 83           case SIZEOF_ARRAY(perl_space_short_invlist):
546 83 50         if (!memcmp(ila, perl_space_short_invlist, sizeof(perl_space_short_invlist)))
547             {
548             #ifdef DEBUG_dump_invlist
549             fprintf(stderr, "NOT_SPACE_BLOCK\n");
550             #endif
551 83           mask = NOT_SPACE_BLOCK;
552             }
553              
554 83           break;
555              
556 0           case SIZEOF_ARRAY(horizontal_space_invlist):
557 0 0         if (!memcmp(ila, horizontal_space_invlist, sizeof(horizontal_space_invlist)))
558             {
559             #ifdef DEBUG_dump_invlist
560             fprintf(stderr, "NOT_HORIZONTAL_SPACE_BLOCK\n");
561             #endif
562 0           mask = NOT_HORIZONTAL_SPACE_BLOCK;
563             }
564              
565 0           break;
566              
567 0           case SIZEOF_ARRAY(horizontal_space_invlist) - 1:
568 0 0         if (!memcmp(ila, horizontal_space_invlist + 1,
569             sizeof(horizontal_space_invlist) - sizeof(horizontal_space_invlist[0])))
570             {
571             #ifdef DEBUG_dump_invlist
572             fprintf(stderr, "HORIZONTAL_SPACE_BLOCK\n");
573             #endif
574 0           mask = HORIZONTAL_SPACE_BLOCK;
575             }
576              
577 0           break;
578              
579 0           case SIZEOF_ARRAY(vertical_space_invlist):
580 0 0         if (!memcmp(ila, vertical_space_invlist, sizeof(vertical_space_invlist)))
581             {
582             #ifdef DEBUG_dump_invlist
583             fprintf(stderr, "NOT_VERTICAL_SPACE_BLOCK\n");
584             #endif
585 0           mask = NOT_VERTICAL_SPACE_BLOCK;
586             }
587              
588 0           break;
589              
590 0           case SIZEOF_ARRAY(vertical_space_invlist) - 1:
591 0 0         if (!memcmp(ila, vertical_space_invlist + 1,
592             sizeof(vertical_space_invlist) - sizeof(vertical_space_invlist[0])))
593             {
594             #ifdef DEBUG_dump_invlist
595             fprintf(stderr, "VERTICAL_SPACE_BLOCK\n");
596             #endif
597 0           mask = VERTICAL_SPACE_BLOCK;
598             }
599              
600 0           break;
601              
602 0           case SIZEOF_ARRAY(xposix_digit_invlist):
603 0 0         if (!memcmp(ila, xposix_digit_invlist, sizeof(xposix_digit_invlist)))
604             {
605             #ifdef DEBUG_dump_invlist
606             fprintf(stderr, "NOT_NUMBER_BLOCK\n");
607             #endif
608 0           mask = NOT_NUMBER_BLOCK;
609             }
610              
611 0           break;
612              
613 0           case SIZEOF_ARRAY(xposix_digit_invlist) - 1:
614 0 0         if (!memcmp(ila, xposix_digit_invlist + 1,
615             sizeof(xposix_digit_invlist) - sizeof(xposix_digit_invlist[0])))
616             {
617             #ifdef DEBUG_dump_invlist
618             fprintf(stderr, "NUMBER_BLOCK\n");
619             #endif
620 0           mask = NUMBER_BLOCK;
621             }
622              
623 0           break;
624              
625 0           case SIZEOF_ARRAY(xposix_alnum_invlist):
626 0 0         if (!memcmp(ila, xposix_alnum_invlist, sizeof(xposix_alnum_invlist)))
627             {
628             #ifdef DEBUG_dump_invlist
629             fprintf(stderr, "NOT_ALNUM_BLOCK\n");
630             #endif
631 0           mask = NOT_ALNUM_BLOCK;
632             }
633              
634 0           break;
635              
636 0           case SIZEOF_ARRAY(xposix_alnum_invlist) - 1:
637 0 0         if (!memcmp(ila, xposix_alnum_invlist + 1,
638             sizeof(xposix_alnum_invlist) - sizeof(xposix_alnum_invlist[0])))
639             {
640             #ifdef DEBUG_dump_invlist
641             fprintf(stderr, "ALNUM_BLOCK\n");
642             #endif
643 0           mask = ALNUM_BLOCK;
644             }
645              
646 0           break;
647              
648 0           case SIZEOF_ARRAY(xposix_alpha_invlist):
649 0 0         if (!memcmp(ila, xposix_alpha_invlist, sizeof(xposix_alpha_invlist)))
650             {
651             #ifdef DEBUG_dump_invlist
652             fprintf(stderr, "NOT_ALPHA_BLOCK\n");
653             #endif
654 0           mask = NOT_ALPHA_BLOCK;
655             }
656              
657 0           break;
658              
659 0           case SIZEOF_ARRAY(xposix_alpha_invlist) - 1:
660 0 0         if (!memcmp(ila, xposix_alpha_invlist + 1,
661             sizeof(xposix_alpha_invlist) - sizeof(xposix_alpha_invlist[0])))
662             {
663             #ifdef DEBUG_dump_invlist
664             fprintf(stderr, "ALPHA_BLOCK\n");
665             #endif
666 0           mask = ALPHA_BLOCK;
667             }
668              
669 0           break;
670              
671 0           case SIZEOF_ARRAY(xposix_word_invlist):
672 0 0         if (!memcmp(ila, xposix_word_invlist, sizeof(xposix_word_invlist)))
673             {
674             #ifdef DEBUG_dump_invlist
675             fprintf(stderr, "NOT_ALPHA_BLOCK\n");
676             #endif
677 0           mask = NOT_ALPHA_BLOCK;
678             }
679              
680 0           break;
681              
682 0           case SIZEOF_ARRAY(xposix_word_invlist) - 1:
683 0 0         if (!memcmp(ila, xposix_word_invlist + 1,
684             sizeof(xposix_word_invlist) - sizeof(xposix_word_invlist[0])))
685             {
686             #ifdef DEBUG_dump_invlist
687             fprintf(stderr, "ALPHA_BLOCK\n");
688             #endif
689 0           mask = ALPHA_BLOCK;
690             }
691              
692 0           break;
693              
694 0           case SIZEOF_ARRAY(xposix_xdigit_invlist):
695 0 0         if (!memcmp(ila, xposix_xdigit_invlist, sizeof(xposix_xdigit_invlist)))
696             {
697             #ifdef DEBUG_dump_invlist
698             fprintf(stderr, "NOT_NUMBER_BLOCK\n");
699             #endif
700 0           mask = NOT_NUMBER_BLOCK;
701             }
702              
703 0           break;
704              
705 0           case SIZEOF_ARRAY(xposix_xdigit_invlist) - 1:
706 0 0         if (!memcmp(ila, xposix_xdigit_invlist + 1,
707             sizeof(xposix_xdigit_invlist) - sizeof(xposix_xdigit_invlist[0])))
708             {
709             #ifdef DEBUG_dump_invlist
710             fprintf(stderr, "NUMBER_BLOCK\n");
711             #endif
712 0           mask = NUMBER_BLOCK;
713             }
714              
715 0           break;
716             }
717              
718 83 50         if (mask)
719             {
720 83 50         if (invert)
721             {
722 83           mask = MIRROR_BLOCK(mask);
723             }
724              
725 83           *map = extend_mask(mask);
726 83           return 1;
727             }
728              
729             #ifdef DEBUG_dump_invlist
730             div[0] = 0;
731             div[2] = 0;
732             for (i = 0; i < ill; ++i)
733             {
734             fprintf(stderr, "%s0x%x", div, (int)(ila[i]));
735             div[0] = ',';
736             div[1] = '\n';
737             }
738              
739             fprintf(stderr, "\n");
740             #endif
741              
742 0           return 0;
743             }
744              
745 85           static int convert_regclass_map(Arrow *a, U32 *map)
746             {
747             regexp_internal *pr;
748             U32 n;
749             struct reg_data *rdata;
750              
751             /* fprintf(stderr, "enter convert_regclass_map\n"); */
752              
753             assert((OP(a->rn) == ANYOF) || (OP(a->rn) == ANYOFD));
754              
755             /* basically copied from regexec.c:regclass_swash */
756 85           n = ARG_LOC(a->rn);
757 85           pr = RXi_GET(a->origin);
758 85 50         if (!pr) /* this should have been tested by find_internal during
759             initialization, but just in case... */
760             {
761 0           rc_error = "regexp_internal not found";
762 0           return -1;
763             }
764              
765 85           rdata = pr->data;
766              
767 85 50         if ((n < rdata->count) &&
768 85 50         (rdata->what[n] == 's')) {
769 85           SV *rv = (SV *)(rdata->data[n]);
770 85           AV *av = (AV *)SvRV(rv);
771 85           SV **ary = AvARRAY(av);
772 85           SV *si = *ary;
773              
774             /* from get_regclass_nonbitmap_data of perl 5.30.0: invlist is
775             in ary[0] */
776 85 100         if (si) /* not so unconditional in Perl 5.32 */
777             {
778 83           return convert_invlist_to_map(si,
779 83           !!(FLAGS(a->rn) & ANYOF_INVERT),
780             map);
781             }
782             else
783             {
784             /* fprintf(stderr, "invlist not found\n"); */
785 2           return 0;
786             }
787             }
788              
789 0           rc_error = "regclass not found";
790 0           return -1;
791             }
792              
793             /* lifted from Perl__get_regclass_nonbitmap_data */
794 108           static SV *get_invlist_sv(Arrow *a)
795             {
796 108           RXi_GET_DECL(a->origin, progi);
797 108           struct reg_data *data = progi->data;
798              
799             assert((OP(a->rn) == ANYOF) || (OP(a->rn) == ANYOFD));
800              
801 108 50         if (data && data->count)
    50          
802             {
803 108           const U32 n = ARG_LOC(a->rn);
804              
805 108 50         if (data->what[n] == 's')
806             {
807 108           SV * const rv = MUTABLE_SV(data->data[n]);
808 108           AV * const av = MUTABLE_AV(SvRV(rv));
809 108           SV **const ary = AvARRAY(av);
810              
811 108           return *ary;
812             }
813             }
814              
815 0           return 0;
816             }
817              
818             /* returns 1 OK (map set), 0 map not recognized/representable, -1
819             unexpected input (rc_error set) */
820 89           static int convert_map(Arrow *a, U32 *map)
821             {
822             /* fprintf(stderr, "enter convert_map\n"); */
823              
824             assert((OP(a->rn) == ANYOF) || (OP(a->rn) == ANYOFD));
825             assert(map);
826              
827 89 100         if (ANYOF_FLAGS(a->rn) & (ANYOF_HAS_EXTRA_RUNTIME_MATCHES | ANYOF_INVERT))
828             {
829 85           return convert_regclass_map(a, map);
830             }
831             else
832             {
833             /* fprintf(stderr, "zero map\n"); */
834 4           *map = 0;
835 4           return 1;
836             }
837             }
838              
839             /* returns 1 OK (map set), 0 map not recognized/representable */
840 5245           static int convert_class_narrow(Arrow *a, U32 *map)
841             {
842             /* fprintf(stderr, "enter convert_class_narrow\n"); */
843              
844             assert(map);
845              
846 5245 50         if (FLAGS(a->rn) >= SIZEOF_ARRAY(posix_regclass_blocks))
847             {
848             /* fprintf(stderr, "unknown class %d\n", FLAGS(a->rn)); */
849 0           return 0;
850             }
851              
852 5245           U32 mask = posix_regclass_blocks[FLAGS(a->rn)];
853 5245 50         if (!mask)
854             {
855             /* fprintf(stderr, "class %d ignored\n", FLAGS(a->rn)); */
856 0           return 0;
857             }
858              
859 5245           *map = mask;
860 5245           return 1;
861             }
862              
863 410           static int convert_anyofr_to_bitmap(Arrow *a, unsigned char *b)
864             {
865 410           regnode *n = a->rn;
866 410           U32 arg = ARG_LOC(n);
867 410           U32 delta = arg & 0xFFF00000;
868 410           U32 start = arg & 0xFFFFF;
869             unsigned i;
870             BitFlag bf;
871              
872 410           delta >>= 20;
873 410 50         if ((start != FLAGS(n)) || ((start + delta) >= 256)) /* UTF-8 not supported */
    50          
874             {
875             /* fprintf(stderr, "needs UTF-8\n"); */
876 0           return 0;
877             }
878              
879 410           memset(b, 0, ANYOF_BITMAP_SIZE);
880 2627 100         for (i = 0; i <= delta; i++)
881             {
882 2217           init_bit_flag(&bf, start + i);
883 2217           b[bf.offs] |= bf.mask;
884             }
885              
886 410           return 1;
887             }
888              
889             /* Adapted from regcomp.c:get_ANYOFM_contents. b must point to
890             ANYOF_BITMAP_SIZE bytes. Returns 1 OK (b set), 0 matches something
891             above the bitmap. */
892 1187           static int convert_anyofm_to_bitmap(Arrow *a, unsigned char *b)
893             {
894 1187           regnode *n = a->rn;
895 1187           U8 lowest = (U8)ARG_LOC(n);
896 1187           unsigned count = 0;
897 1187           unsigned needed = 1U << PL_bitcount[(U8)~FLAGS(n)];
898             unsigned i;
899             BitFlag bf;
900              
901 1187           memset(b, 0, ANYOF_BITMAP_SIZE);
902 21908 50         for (i = lowest; i <= 0xFF; i++)
903             {
904 21908 100         if ((i & FLAGS(n)) == ARG_LOC(n))
905             {
906 2130           init_bit_flag(&bf, i);
907 2130           b[bf.offs] |= bf.mask;
908              
909 2130 100         if (++count >= needed)
910             {
911 1187           return 1;
912             }
913             }
914             }
915              
916 0           return 0;
917             }
918              
919             /* returns 1 OK (map set), 0 map not recognized/representable */
920 4102           static int convert_class(Arrow *a, U32 *map)
921             {
922 4102 50         if (!convert_class_narrow(a, map))
923             {
924 0           return 0;
925             }
926              
927 4102           *map = extend_mask(*map);
928 4102           return 1;
929             }
930              
931 950           static int convert_negative_class(Arrow *a, U32 *map)
932             {
933             U32 mask;
934              
935 950 50         if (!convert_class_narrow(a, &mask))
936             {
937 0           return 0;
938             }
939              
940 950           *map = extend_mask(MIRROR_BLOCK(mask));
941 950           return 1;
942             }
943              
944 658           static int get_assertion_offset(regnode *p)
945             {
946             int offs;
947              
948 658           offs = ARG_LOC(p);
949 658 50         if (offs <= 2)
950             {
951 0           rc_error = "Assertion offset too small";
952 0           return -1;
953             }
954              
955 658           return offs;
956             }
957              
958 6           static int get_alt_assertion_arg(regnode *p)
959             {
960             int arg;
961              
962 6           arg = ARG_LOC(p);
963 6 50         if (arg < 0)
964             {
965 0           rc_error = "Assertion argument too small";
966 0           return -1;
967             }
968              
969 6           return arg;
970             }
971              
972 6           static int get_alt_assertion_size(regnode *p)
973             {
974 6 50         if (NEXT_OFF(p) < 2)
975             {
976 0           rc_error = "Assertion size too small";
977 0           return -1;
978             }
979              
980 6           return NEXT_OFF(p);
981             }
982              
983 3061           static int get_synth_offset(regnode *p)
984             {
985             assert(!NEXT_OFF(p));
986              
987 3061 100         if (((OP(p) == EXACT) || (OP(p) == EXACTF) || (OP(p) == EXACTFU)) &&
    50          
    50          
988 1484 50         (FLAGS(p) == 1))
989             {
990 1484           return 2;
991             }
992 1577 100         else if (trivial_nodes[OP(p)] ||
993 536 100         (OP(p) == REG_ANY) || (OP(p) == SANY) ||
    100          
994 442 100         (OP(p) == POSIXD) || (OP(p) == NPOSIXD) ||
    100          
995 352 100         (OP(p) == POSIXU) || (OP(p) == NPOSIXU) ||
    100          
996 277 100         (OP(p) == POSIXA) || (OP(p) == NPOSIXA) ||
    100          
997 189 100         (OP(p) == LNBREAK))
998             {
999 1392           return 1;
1000             }
1001 185 100         else if ((OP(p) == ANYOF) || (OP(p) == ANYOFD))
    100          
1002             {
1003             /* other flags obviously exist, but they haven't been seen yet
1004             and it isn't clear what they mean */
1005 115           unsigned int unknown = FLAGS(p) &
1006             ~(ANYOF_INVERT | ANYOF_HAS_EXTRA_RUNTIME_MATCHES);
1007 115 50         if (unknown)
1008             {
1009             /* p[10] seems always 0 on Linux, but 0xfbfaf9f8 seen on
1010             Windows; for '[\\w\\-_.]+\\.', both 0 and 0x20202020
1011             observed in p[11] - wonder what those are... */
1012 0           rc_error = "Unknown bitmap format";
1013 0           return -1;
1014             }
1015              
1016 115           return 10;
1017             }
1018 70 100         else if (OP(p) == ANYOFR)
1019             {
1020 10           return 2;
1021             }
1022 60 100         else if (OP(p) == ANYOFM)
1023             {
1024 35           return 2;
1025             }
1026 25 100         else if (OP(p) == NANYOFM)
1027             {
1028 19           return 2;
1029             }
1030 6 100         else if ((OP(p) == IFMATCH) || (OP(p) == UNLESSM) ||
    50          
1031 0 0         (OP(p) == SUSPEND))
1032             {
1033 6           return get_assertion_offset(p);
1034             }
1035              
1036             /* fprintf(stderr, "type %d\n", p->type); */
1037 0           rc_error = "Offset not set";
1038 0           return -1;
1039             }
1040              
1041 2930           static int get_size(regnode *rn)
1042             {
1043             int offs;
1044 2930           regnode *e = rn;
1045              
1046 7088 100         while (OP(e) != END)
1047             {
1048 4158 100         offs = GET_OFFSET(e);
1049 4158 50         if (offs <= 0)
1050             {
1051 0           return -1;
1052             }
1053              
1054 4158           e += offs;
1055             }
1056              
1057 2930           return e - rn + 1;
1058             }
1059              
1060             /* #define DEBUG_dump_data */
1061              
1062 18322           static regnode *find_internal(regexp *pt)
1063             {
1064             regexp_internal *pr;
1065             regnode *p;
1066             #ifdef DEBUG_dump_data
1067             struct reg_data *rdata;
1068             int n;
1069             #endif
1070              
1071             assert(pt);
1072              
1073             /* ActivePerl Build 1001 doesn't export PL_core_reg_engine, so
1074             the test, however useful, wouldn't link... */
1075             #if !defined(ACTIVEPERL_PRODUCT)
1076 18322 50         if (pt->engine && (pt->engine != &PL_core_reg_engine))
    50          
1077             {
1078 0           rc_error = "Alternative regexp engine not supported";
1079 0           return 0;
1080             }
1081             #endif
1082              
1083 18322           pr = RXi_GET(pt);
1084 18322 50         if (!pr)
1085             {
1086 0           rc_error = "Internal regexp not set";
1087 0           return 0;
1088             }
1089              
1090 18322           p = pr->program;
1091 18322 50         if (!p)
1092             {
1093 0           rc_error = "Compiled regexp not set";
1094 0           return 0;
1095             }
1096              
1097 18322 50         if (!((FLAGS(p) == REG_MAGIC) &&
1098 18322 50         (NEXT_OFF(p) == 0)))
1099             {
1100             /* fprintf(stderr, "%d %d %d\n", p->flags, p->type, p->next_off); */
1101 0           rc_error = "Invalid regexp signature";
1102 0           return 0;
1103             }
1104              
1105             #ifdef DEBUG_dump_data
1106             rdata = pr->data;
1107             if (rdata)
1108             {
1109             fprintf(stderr, "regexp data count = %d\n", (int)(rdata->count));
1110             for (n = 0; n < rdata->count; ++n)
1111             {
1112             fprintf(stderr, "\twhat[%d] = %c\n", n, rdata->what[n]);
1113             }
1114             }
1115             else
1116             {
1117             fprintf(stderr, "no regexp data\n");
1118             }
1119             #endif
1120              
1121 18322           return p + 1;
1122             }
1123              
1124 216           static unsigned char parse_hex_digit(char d)
1125             {
1126             unsigned char rv;
1127              
1128 216           d = tolower(d);
1129              
1130 216 50         if (('0' <= d) && (d <= '9'))
    100          
1131             {
1132 149           rv = d - '0';
1133             }
1134             else
1135             {
1136 67           rv = 10 + (d - 'a');
1137             }
1138              
1139 216           return rv;
1140             }
1141              
1142 108           static unsigned char parse_hex_byte(const char *first)
1143             {
1144 108           return 16 * parse_hex_digit(*first) +
1145 108           parse_hex_digit(first[1]);
1146             }
1147              
1148 18336           static unsigned get_forced_semantics(REGEXP *pt)
1149             {
1150 18336           const char *precomp = RX_PRECOMP(pt);
1151 18336           U32 prelen = RX_PRELEN(pt);
1152 18336           int quoted = 0;
1153             int matched;
1154 18336           unsigned forced = 0;
1155             U32 i;
1156             BitFlag bf;
1157             char c;
1158              
1159             /* fprintf(stderr, "precomp = %*s\n", (int)prelen, precomp); */
1160              
1161 136061 100         for (i = 0; i < prelen; ++i)
1162             {
1163 117725           c = precomp[i];
1164              
1165 117725 100         if (c == '.')
1166             {
1167             /* a dot does match Unicode character - the problem is
1168             that character might take up multiple bytes, and we
1169             don't want to match just one of them... */
1170 1252           forced |= FORCED_BYTE;
1171             }
1172              
1173 117725 100         if (!quoted)
1174             {
1175             /* technically, the backslash might be in a comment, but
1176             parsing that is too much hassle */
1177 105671 100         if (c == '\\')
1178             {
1179 12054           quoted = 1;
1180             }
1181             }
1182             else
1183             {
1184 12054           matched = 0;
1185              
1186 12054 100         if (c == 'N')
1187             {
1188             /* we have special cases only for \r & \n... */
1189 441 100         if ((i + 8 < prelen) &&
1190 24 100         !memcmp(precomp + i + 1, "{U+00", 5) &&
1191 11 50         isxdigit(precomp[i + 6]) && isxdigit(precomp[i + 7]) &&
    50          
1192 11 50         (precomp[i + 8] == '}'))
1193 11           {
1194 11           unsigned char x = parse_hex_byte(precomp + i + 6);
1195 11 100         if ((x != '\r') && (x != '\n'))
    50          
1196             {
1197 0           forced |= FORCED_CHAR;
1198             }
1199              
1200 11           i += 8;
1201             }
1202 430 100         else if ((i + 1 < prelen) &&
1203 220 100         (precomp[i + 1] == '{'))
1204             {
1205 13           forced |= FORCED_CHAR;
1206             }
1207              
1208             /* otherwise it's not an escape, but the inverse of \n
1209             - we aren't interested in that */
1210              
1211 441           matched = 1;
1212             }
1213 11613 100         else if (c == 'x')
1214             {
1215 117 50         if ((i + 2 < prelen) &&
1216 117 100         isxdigit(precomp[i + 1]) && isxdigit(precomp[i + 2]))
    50          
1217             {
1218 97           unsigned char x = parse_hex_byte(precomp + i + 1);
1219 97 100         if ((x != '\r') && (x != '\n'))
    100          
1220             {
1221 85           forced |= FORCED_BYTE;
1222             }
1223              
1224 97           matched = 1;
1225 97           i += 2;
1226             }
1227             }
1228              
1229             /* ...and we aren't bothering to parse octal numbers
1230             and \x{n+} at all... */
1231              
1232 12054 100         if (!matched)
1233             {
1234 11516           init_bit_flag(&bf, (unsigned char)c);
1235 11516 100         if (forced_byte[bf.offs] & bf.mask)
1236             {
1237 340           forced |= FORCED_BYTE;
1238             }
1239             }
1240              
1241 12054           quoted = 0;
1242             }
1243             }
1244              
1245 18336           return forced;
1246             }
1247              
1248 921           static regnode *alloc_alt(regnode *p, int sz)
1249             {
1250             regnode *alt;
1251              
1252 921           alt = (regnode *)malloc(sizeof(regnode) * sz);
1253 921 50         if (!alt)
1254             {
1255 0           rc_error = "Could not allocate memory for regexp copy";
1256 0           return 0;
1257             }
1258              
1259 921           memcpy(alt, p, sizeof(regnode) * sz);
1260              
1261 921           return alt;
1262             }
1263              
1264 384           static regnode *alloc_terminated(regnode *p, int sz)
1265             {
1266             regnode *alt;
1267             int last;
1268              
1269             /* fprintf(stderr, "enter alloc_terminated(, %d\n", sz); */
1270              
1271             assert(sz > 0);
1272 384           alt = alloc_alt(p, sz);
1273 384 50         if (!alt)
1274             {
1275 0           return 0;
1276             }
1277              
1278 384           last = OP(alt + (sz - 1));
1279             /* fprintf(stderr, "type: %d\n", last); */
1280 384 50         if ((last >= REGNODE_MAX) || !trivial_nodes[last])
    50          
1281             {
1282 0           rc_error = "Alternative doesn't end like subexpression";
1283 0           return 0;
1284             }
1285              
1286 384           OP(alt + (sz - 1)) = END;
1287 384           return alt;
1288             }
1289              
1290 15556           static int bump_exact(Arrow *a)
1291             {
1292             int offs;
1293              
1294             assert((OP(a->rn) == EXACT) || (OP(a->rn) == EXACTF) ||
1295             (OP(a->rn) == EXACTFU) || (OP(a->rn) == EXACT_REQ8));
1296              
1297 15556 100         offs = GET_OFFSET(a->rn);
1298 15556 50         if (offs <= 0)
1299             {
1300 0           return -1;
1301             }
1302              
1303 15556 100         if (OP(a->rn) == EXACT_REQ8)
1304             {
1305 30 100         while (*(((unsigned char *)((a)->rn + 1)) + (a)->spent) & 0x80)
1306             {
1307 18           ++(a->spent);
1308             }
1309             }
1310              
1311 15556 100         if (++(a->spent) >= FLAGS(a->rn))
1312             {
1313 10225           a->spent = 0;
1314 10225           a->rn += offs;
1315             }
1316              
1317 15556           return 1;
1318             }
1319              
1320 19084           static int bump_regular(Arrow *a)
1321             {
1322             int offs;
1323              
1324             assert(OP(a->rn) != END);
1325             assert(OP(a->rn) != EXACT);
1326             assert(OP(a->rn) != EXACTF);
1327             assert(!a->spent);
1328              
1329 19084 100         offs = GET_OFFSET(a->rn);
1330 19084 50         if (offs <= 0)
1331             {
1332 0           return -1;
1333             }
1334              
1335 19084           a->rn += offs;
1336 19084           return 1;
1337             }
1338              
1339 32814           static int bump_with_check(Arrow *a)
1340             {
1341 32814 100         if (OP(a->rn) == END)
1342             {
1343 74           return 0;
1344             }
1345 32740 100         else if ((OP(a->rn) == EXACT) || (OP(a->rn) == EXACTF) ||
    100          
1346 17774 100         (OP(a->rn) == EXACTFU) || (OP(a->rn) == EXACT_REQ8))
    100          
1347             {
1348 15556           return bump_exact(a);
1349             }
1350             else
1351             {
1352 17184           return bump_regular(a);
1353             }
1354             }
1355              
1356 92           static int get_jump_offset(regnode *p)
1357             {
1358             int offs;
1359             regnode *q;
1360              
1361             assert(OP(p) != END);
1362              
1363 92 50         offs = GET_OFFSET(p);
1364 92 50         if (offs <= 0)
1365             {
1366 0           return -1;
1367             }
1368              
1369 92           q = p + offs;
1370 124 100         while (trivial_nodes[OP(q)])
1371             {
1372 32 100         offs = GET_OFFSET(q);
1373 32 50         if (offs <= 0)
1374             {
1375 0           return -1;
1376             }
1377              
1378 32           q += offs;
1379             }
1380              
1381 92           return q - p;
1382             }
1383              
1384 18343           REGEXP *rc_regcomp(SV *rs)
1385             {
1386             REGEXP *rx;
1387              
1388 18343 50         if (!rs)
1389             {
1390 0           croak("No regexp to compare");
1391             }
1392              
1393 18343           rx = pregcomp(rs, 0);
1394 18338 50         if (!rx)
1395             {
1396 0           croak("Cannot compile regexp");
1397             }
1398              
1399 18338           return rx;
1400             }
1401              
1402 18338           void rc_regfree(REGEXP *rx)
1403             {
1404 18338 50         if (rx)
1405             {
1406 18338           pregfree(rx);
1407             }
1408 18338           }
1409              
1410 6343           static int compare_mismatch(int anchored, Arrow *a1, Arrow *a2)
1411             {
1412             int rv;
1413              
1414             /* fprintf(stderr, "enter compare_mismatch(%d...)\n", anchored); */
1415              
1416 6343 100         if (anchored)
1417             {
1418 679           return 0;
1419             }
1420             else
1421             {
1422 5664           rv = bump_with_check(a1);
1423 5664 100         if (rv <= 0)
1424             {
1425 74           return rv;
1426             }
1427              
1428 5590           return compare(0, a1, a2);
1429             }
1430             }
1431              
1432 13072           static int compare_tails(int anchored, Arrow *a1, Arrow *a2)
1433             {
1434             Arrow tail1, tail2;
1435             int rv;
1436              
1437             /* is it worth using StructCopy? */
1438 13072           tail1 = *a1;
1439 13072           rv = bump_with_check(&tail1);
1440 13072 50         if (rv <= 0)
1441             {
1442 0           return rv;
1443             }
1444              
1445 13072           tail2 = *a2;
1446 13072           rv = bump_with_check(&tail2);
1447 13072 50         if (rv <= 0)
1448             {
1449 0           return rv;
1450             }
1451              
1452 13072           rv = compare(1, &tail1, &tail2);
1453 13072 50         if (rv < 0)
1454             {
1455 0           return rv;
1456             }
1457              
1458 13072 100         if (!rv)
1459             {
1460 265           rv = compare_mismatch(anchored, a1, a2);
1461             }
1462             else
1463             {
1464 12807           *a1 = tail1;
1465 12807           *a2 = tail2;
1466             }
1467              
1468 13072           return rv;
1469             }
1470              
1471 826           static int compare_left_tail(int anchored, Arrow *a1, Arrow *a2)
1472             {
1473             Arrow tail1;
1474             int rv;
1475              
1476 826           tail1 = *a1;
1477 826           rv = bump_with_check(&tail1);
1478 826 50         if (rv <= 0)
1479             {
1480 0           return rv;
1481             }
1482              
1483 826           return compare(anchored, &tail1, a2);
1484             }
1485              
1486 268           static int compare_after_assertion(int anchored, Arrow *a1, Arrow *a2)
1487             {
1488             Arrow tail1;
1489             int offs;
1490              
1491             assert((OP(a1->rn) == IFMATCH) || (OP(a1->rn) == UNLESSM));
1492              
1493 268           offs = get_assertion_offset(a1->rn);
1494 268 50         if (offs < 0)
1495             {
1496 0           return offs;
1497             }
1498              
1499 268           tail1.origin = a1->origin;
1500 268           tail1.rn = a1->rn + offs;
1501 268           tail1.spent = 0;
1502 268           return compare(anchored, &tail1, a2);
1503             }
1504              
1505 0           static int compare_after_alt_assertion(int anchored, Arrow *a1, Arrow *a2)
1506             {
1507 0           return compare_left_tail(anchored, a1, a2);
1508             }
1509              
1510 83           static int compare_positive_assertions(int anchored, Arrow *a1, Arrow *a2)
1511             {
1512             regnode *p1, *alt1, *p2, *alt2;
1513             int rv, sz1, sz2;
1514             Arrow left, right;
1515              
1516 83           p1 = a1->rn;
1517 83           p2 = a2->rn;
1518             assert(OP(p1) == IFMATCH);
1519             assert(OP(p2) == IFMATCH);
1520              
1521 83           sz1 = get_assertion_offset(p1);
1522 83 50         if (sz1 < 0)
1523             {
1524 0           return -1;
1525             }
1526              
1527 83           sz2 = get_assertion_offset(p2);
1528 83 50         if (sz2 < 0)
1529             {
1530 0           return -1;
1531             }
1532              
1533 83           alt1 = alloc_terminated(p1 + 2, sz1 - 2);
1534 83 50         if (!alt1)
1535             {
1536 0           return -1;
1537             }
1538              
1539 83           alt2 = alloc_terminated(p2 + 2, sz2 - 2);
1540 83 50         if (!alt2)
1541             {
1542 0           free(alt1);
1543 0           return -1;
1544             }
1545              
1546 83           left.origin = a1->origin;
1547 83           left.rn = alt1;
1548 83           left.spent = 0;
1549 83           right.origin = a2->origin;
1550 83           right.rn = alt2;
1551 83           right.spent = 0;
1552 83           rv = compare(0, &left, &right);
1553              
1554 83           free(alt1);
1555 83           free(alt2);
1556              
1557 83 100         if (rv <= 0)
1558             {
1559 1           return rv;
1560             }
1561              
1562             /* left & right.origin stays a1 & a2->origin, respectively */
1563 82           left.rn = p1 + sz1;
1564 82           left.spent = 0;
1565 82           right.rn = p2 + sz2;
1566 82           right.spent = 0;
1567 82           return compare(anchored, &left, &right);
1568             }
1569              
1570 77           static int compare_negative_assertions(int anchored, Arrow *a1, Arrow *a2)
1571             {
1572             regnode *p1, *alt1, *p2, *alt2;
1573             int rv, sz1, sz2;
1574             Arrow left, right;
1575              
1576 77           p1 = a1->rn;
1577 77           p2 = a2->rn;
1578             assert(OP(p1) == UNLESSM);
1579             assert(OP(p2) == UNLESSM);
1580              
1581 77           sz1 = get_assertion_offset(p1);
1582 77 50         if (sz1 < 0)
1583             {
1584 0           return -1;
1585             }
1586              
1587 77           sz2 = get_assertion_offset(p2);
1588 77 50         if (sz2 < 0)
1589             {
1590 0           return -1;
1591             }
1592              
1593 77           alt1 = alloc_terminated(p1 + 2, sz1 - 2);
1594 77 50         if (!alt1)
1595             {
1596 0           return -1;
1597             }
1598              
1599 77           alt2 = alloc_terminated(p2 + 2, sz2 - 2);
1600 77 50         if (!alt2)
1601             {
1602 0           free(alt1);
1603 0           return -1;
1604             }
1605              
1606 77           left.origin = a1->origin;
1607 77           left.rn = alt1;
1608 77           left.spent = 0;
1609 77           right.origin = a2->origin;
1610 77           right.rn = alt2;
1611 77           right.spent = 0;
1612 77           rv = compare(0, &right, &left);
1613              
1614 77           free(alt1);
1615 77           free(alt2);
1616              
1617 77 100         if (rv <= 0)
1618             {
1619 2           return rv;
1620             }
1621              
1622             /* left & right.origin stays a1 & a2->origin, respectively */
1623 75           left.rn = p1 + sz1;
1624 75           left.spent = 0;
1625 75           right.rn = p2 + sz2;
1626 75           right.spent = 0;
1627 75           return compare(anchored, &left, &right);
1628             }
1629              
1630 3           static int compare_negative_alt_assertions(int anchored, Arrow *a1, Arrow *a2)
1631             {
1632             regnode *p1, *p2;
1633             int b1, b2, sz1, sz2;
1634              
1635 3           p1 = a1->rn;
1636 3           p2 = a2->rn;
1637             assert(OP(p1) == OPFAIL);
1638             assert(OP(p2) == OPFAIL);
1639              
1640 3           b1 = get_alt_assertion_arg(p1);
1641 3 50         if (b1 < 0)
1642             {
1643 0           return -1;
1644             }
1645              
1646 3           b2 = get_alt_assertion_arg(p2);
1647 3 50         if (b2 < 0)
1648             {
1649 0           return -1;
1650             }
1651              
1652 3 50         if (b1 != b2)
1653             {
1654 0           return compare_mismatch(anchored, a1, a2);
1655             }
1656              
1657 3           sz1 = get_alt_assertion_size(p1);
1658 3 50         if (sz1 < 0)
1659             {
1660 0           return -1;
1661             }
1662              
1663 3           sz2 = get_alt_assertion_size(p2);
1664 3 50         if (sz2 < 0)
1665             {
1666 0           return -1;
1667             }
1668              
1669 3 50         if ((sz1 == 2) && (sz2 == 2))
    50          
1670             {
1671 3           return compare_tails(anchored, a1, a2);
1672             }
1673              
1674             /* Obviously non-empty assertions should be considered as well,
1675             but they weren't seen yet (nor particularly looked for)... */
1676 0           return compare_mismatch(anchored, a1, a2);
1677             }
1678              
1679 32           static int compare_subexpressions(int anchored, Arrow *a1, Arrow *a2)
1680             {
1681             regnode *p1, *alt1, *p2, *alt2;
1682             int rv, sz1, sz2;
1683             Arrow left, right;
1684              
1685 32           p1 = a1->rn;
1686 32           p2 = a2->rn;
1687             assert(OP(p1) == SUSPEND);
1688             assert(OP(p2) == SUSPEND);
1689              
1690 32           sz1 = get_assertion_offset(p1);
1691 32 50         if (sz1 < 0)
1692             {
1693 0           return -1;
1694             }
1695              
1696 32           sz2 = get_assertion_offset(p2);
1697 32 50         if (sz2 < 0)
1698             {
1699 0           return -1;
1700             }
1701              
1702 32           alt1 = alloc_terminated(p1 + 2, sz1 - 2);
1703 32 50         if (!alt1)
1704             {
1705 0           return -1;
1706             }
1707              
1708 32           alt2 = alloc_terminated(p2 + 2, sz2 - 2);
1709 32 50         if (!alt2)
1710             {
1711 0           free(alt1);
1712 0           return -1;
1713             }
1714              
1715 32           left.origin = a1->origin;
1716 32           left.rn = alt1;
1717 32           left.spent = 0;
1718 32           right.origin = a2->origin;
1719 32           right.rn = alt2;
1720 32           right.spent = 0;
1721 32           rv = compare(1, &left, &right);
1722              
1723 32           free(alt1);
1724 32           free(alt2);
1725              
1726 32 100         if (rv <= 0)
1727             {
1728 1           return rv;
1729             }
1730              
1731             /* left & right.origin stays a1 & a2->origin, respectively */
1732 31           left.rn = p1 + sz1;
1733 31           left.spent = 0;
1734 31           right.rn = p2 + sz2;
1735 31           right.spent = 0;
1736 31           return compare(1, &left, &right);
1737             }
1738              
1739 637           static int compare_bol(int anchored, Arrow *a1, Arrow *a2)
1740             {
1741             int rv;
1742              
1743             assert((OP(a1->rn) == MBOL) || (OP(a1->rn) == SBOL));
1744              
1745 637 100         if (anchored)
1746             {
1747 8           return 0;
1748             }
1749              
1750 629 50         if (bump_regular(a1) <= 0)
1751             {
1752 0           return -1;
1753             }
1754              
1755 629           rv = compare(1, a1, a2);
1756 629 100         if (!rv)
1757             {
1758 62           rv = compare_mismatch(0, a1, a2);
1759             }
1760              
1761 629           return rv;
1762             }
1763              
1764 10870           static unsigned char get_bitmap_byte(regnode *p, int i)
1765             {
1766             unsigned char *bitmap;
1767             unsigned char loc;
1768              
1769             assert((OP(p) == ANYOF) || (OP(p) == ANYOFD));
1770              
1771 10870           bitmap = (unsigned char *)(p + 2);
1772 10870 100         if ((i >= 16) && (OP(p) == ANYOFD) &&
    100          
1773 4224 100         (FLAGS(p) & ANYOFD_NON_UTF8_MATCHES_ALL_NON_ASCII__shared))
1774             {
1775 1120           loc = 0xff;
1776             }
1777             else
1778             {
1779 9750           loc = bitmap[i];
1780             }
1781              
1782 10870 100         if (FLAGS(p) & ANYOF_INVERT)
1783             {
1784 5768           loc = ~loc;
1785             }
1786              
1787 10870           return loc;
1788             }
1789              
1790 931           static int compare_bitmaps(int anchored, Arrow *a1, Arrow *a2,
1791             unsigned char *b1, unsigned char *b2)
1792             {
1793             /* Note that aN->flags must be ignored when bN is set (necessary
1794             for ANYOFM, where they aren't really flags and can't be used as
1795             such). */
1796             unsigned char loc1, loc2;
1797             int i;
1798              
1799             /* fprintf(stderr, "enter compare_bitmaps(%d, %d, %d)\n", anchored,
1800             OP(a1->rn), OP(a2->rn)); */
1801              
1802 27355 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
1803             {
1804 26542 100         loc1 = b1 ? b1[i] : get_bitmap_byte(a1->rn, i);
1805 26542 100         loc2 = b2 ? b2[i] : get_bitmap_byte(a2->rn, i);
1806 26542 100         if (loc1 & ~loc2)
1807             {
1808             /* fprintf(stderr, "compare_bitmaps fails at %d: %d does not imply %d\n",
1809             i, loc1, loc2); */
1810 118           return compare_mismatch(anchored, a1, a2);
1811             }
1812             }
1813              
1814 813           return compare_tails(anchored, a1, a2);
1815             }
1816              
1817 145           static int compare_negative_bitmaps(int anchored, Arrow *a1, Arrow *a2,
1818             unsigned char *b1, unsigned char *b2)
1819             {
1820             unsigned char loc1, loc2;
1821             int i;
1822              
1823             assert(b1 && b2);
1824 2521 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
1825             {
1826 2453           loc1 = b1[i];
1827 2453           loc2 = b2[i];
1828 2453 100         if (~loc1 & loc2)
1829             {
1830 77           return compare_mismatch(anchored, a1, a2);
1831             }
1832             }
1833              
1834 68           return compare_tails(anchored, a1, a2);
1835             }
1836              
1837 3           static int compare_anyof_multiline(int anchored, Arrow *a1, Arrow *a2)
1838             {
1839             BitFlag bf;
1840             Arrow tail1, tail2;
1841             unsigned char req;
1842             int i;
1843              
1844             /* fprintf(stderr, "enter compare_anyof_multiline\n"); */
1845              
1846             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
1847             assert((OP(a2->rn) == MBOL) || (OP(a2->rn) == MEOL));
1848              
1849 3           init_bit_flag(&bf, '\n');
1850 4 50         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
1851             {
1852 4 100         req = (i != bf.offs) ? 0 : bf.mask;
1853 4 100         if (get_bitmap_byte(a1->rn, i) != req)
1854             {
1855 3           return compare_mismatch(anchored, a1, a2);
1856             }
1857             }
1858              
1859 0           tail1 = *a1;
1860 0 0         if (bump_regular(&tail1) <= 0)
1861             {
1862 0           return -1;
1863             }
1864              
1865 0           tail2 = *a2;
1866 0 0         if (bump_regular(&tail2) <= 0)
1867             {
1868 0           return -1;
1869             }
1870              
1871 0           return compare(1, &tail1, &tail2);
1872             }
1873              
1874 2           static int compare_anyofr_multiline(int anchored, Arrow *a1, Arrow *a2)
1875             {
1876             unsigned char req;
1877             int i;
1878             BitFlag bf;
1879             Arrow tail1, tail2;
1880             unsigned char left[ANYOF_BITMAP_SIZE];
1881              
1882             assert(OP(a1->rn) == ANYOFR);
1883             assert((OP(a2->rn) == MBOL) || (OP(a2->rn) == MEOL));
1884              
1885 2 50         if (!convert_anyofr_to_bitmap(a1, left))
1886             {
1887 0           return compare_mismatch(anchored, a1, a2);
1888             }
1889              
1890 2           init_bit_flag(&bf, '\n');
1891 4 50         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
1892             {
1893 4 100         req = (i != bf.offs) ? 0 : bf.mask;
1894 4 100         if (left[i] != req)
1895             {
1896 2           return compare_mismatch(anchored, a1, a2);
1897             }
1898             }
1899              
1900 0           tail1 = *a1;
1901 0 0         if (bump_regular(&tail1) <= 0)
1902             {
1903 0           return -1;
1904             }
1905              
1906 0           tail2 = *a2;
1907 0 0         if (bump_regular(&tail2) <= 0)
1908             {
1909 0           return -1;
1910             }
1911              
1912 0           return compare(1, &tail1, &tail2);
1913             }
1914              
1915 3           static int compare_anyofm_multiline(int anchored, Arrow *a1, Arrow *a2)
1916             {
1917             unsigned char req;
1918             int i;
1919             BitFlag bf;
1920             Arrow tail1, tail2;
1921             unsigned char left[ANYOF_BITMAP_SIZE];
1922              
1923             assert(OP(a1->rn) == ANYOFM);
1924             assert((OP(a2->rn) == MBOL) || (OP(a2->rn) == MEOL));
1925              
1926 3 50         if (!convert_anyofm_to_bitmap(a1, left))
1927             {
1928 0           return compare_mismatch(anchored, a1, a2);
1929             }
1930              
1931 3           init_bit_flag(&bf, '\n');
1932 6 50         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
1933             {
1934 6 100         req = (i != bf.offs) ? 0 : bf.mask;
1935 6 100         if (left[i] != req)
1936             {
1937 3           return compare_mismatch(anchored, a1, a2);
1938             }
1939             }
1940              
1941 0           tail1 = *a1;
1942 0 0         if (bump_regular(&tail1) <= 0)
1943             {
1944 0           return -1;
1945             }
1946              
1947 0           tail2 = *a2;
1948 0 0         if (bump_regular(&tail2) <= 0)
1949             {
1950 0           return -1;
1951             }
1952              
1953 0           return compare(1, &tail1, &tail2);
1954             }
1955              
1956 2           static int compare_nanyofm_multiline(int anchored, Arrow *a1, Arrow *a2)
1957             {
1958             unsigned char req;
1959             int i;
1960             BitFlag bf;
1961             Arrow tail1, tail2;
1962             unsigned char left[ANYOF_BITMAP_SIZE];
1963              
1964             assert(OP(a1->rn) == NANYOFM);
1965             assert((OP(a2->rn) == MBOL) || (OP(a2->rn) == MEOL));
1966              
1967 2 50         if (!convert_anyofm_to_bitmap(a1, left))
1968             {
1969 0           return compare_mismatch(anchored, a1, a2);
1970             }
1971              
1972 66 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
1973             {
1974 64           left[i] = ~left[i];
1975             }
1976              
1977 2           init_bit_flag(&bf, '\n');
1978 2 50         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
1979             {
1980 2 50         req = (i != bf.offs) ? 0 : bf.mask;
1981 2 50         if (left[i] != req)
1982             {
1983 2           return compare_mismatch(anchored, a1, a2);
1984             }
1985             }
1986              
1987 0           tail1 = *a1;
1988 0 0         if (bump_regular(&tail1) <= 0)
1989             {
1990 0           return -1;
1991             }
1992              
1993 0           tail2 = *a2;
1994 0 0         if (bump_regular(&tail2) <= 0)
1995             {
1996 0           return -1;
1997             }
1998              
1999 0           return compare(1, &tail1, &tail2);
2000             }
2001              
2002 81           static int compare_anyof_anyof(int anchored, Arrow *a1, Arrow *a2)
2003             {
2004             int extra_left;
2005              
2006             /* fprintf(stderr, "enter compare_anyof_anyof(%d\n", anchored); */
2007              
2008             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
2009             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
2010              
2011 81           extra_left = ANYOF_FLAGS(a1->rn) &
2012             ANYOF_HAS_EXTRA_RUNTIME_MATCHES;
2013 81 100         if (extra_left)
2014             {
2015             U32 m1, m2;
2016             int cr1, cr2;
2017              
2018             /* fprintf(stderr, "comparing invlists: left flags = 0x%x, right flags = 0x%x\n", (int)(a1->rn->flags), (int)(a2->rn->flags)); */
2019             /* before recognizing standard invlists, check whether they
2020             aren't the same - this duplicates the code to get to the
2021             invlist, but works even for non-standard ones,
2022             e.g. [\da] */
2023 54 50         if ((FLAGS(a1->rn) & ANYOF_HAS_EXTRA_RUNTIME_MATCHES) &&
2024 54 50         (FLAGS(a2->rn) & ANYOF_HAS_EXTRA_RUNTIME_MATCHES))
2025             {
2026 54           SV *invlist1 = get_invlist_sv(a1);
2027 54           SV *invlist2 = get_invlist_sv(a2);
2028 54 100         if (invlist1 && invlist2)
    50          
2029             {
2030 53           UV ill1 = get_invlist_len(invlist1);
2031 53           UV ill2 = get_invlist_len(invlist2);
2032 53 50         if (ill1 && (ill1 == ill2))
    50          
2033             {
2034 53           UV *ila1 = invlist_array(invlist1);
2035 53           UV *ila2 = invlist_array(invlist2);
2036 53 50         if (!memcmp(ila1, ila2, ill1 * sizeof(UV)))
2037             {
2038 54           return compare_bitmaps(anchored, a1, a2, 0, 0);
2039             }
2040             }
2041             }
2042             }
2043              
2044 1           cr1 = convert_map(a1, &m1);
2045 1 50         if (cr1 == -1)
2046             {
2047 0           return -1;
2048             }
2049              
2050 1           cr2 = convert_map(a2, &m2);
2051 1 50         if (cr2 == -1)
2052             {
2053 0           return -1;
2054             }
2055              
2056             /* clearly this hould happen at a lower level, but there it
2057             breaks other paths... */
2058 1 50         if (m2 & NOT_ALNUM_BLOCK)
2059             {
2060 0           m2 |= NOT_ALPHA_BLOCK | NOT_NUMBER_BLOCK;
2061 0           m2 = extend_mask(m2);
2062             }
2063              
2064 1 50         if (!cr1 || !cr2 || (m1 & ~m2))
    0          
    0          
2065             {
2066             /* fprintf(stderr, "cr1 = %d, cr2 = %d, m1 = 0x%x, m2 = 0x%x\n",
2067             cr1, cr2, (unsigned)m1, (unsigned)m2); */
2068 1           return compare_mismatch(anchored, a1, a2);
2069             }
2070             }
2071              
2072 27           return compare_bitmaps(anchored, a1, a2, 0, 0);
2073             }
2074              
2075 3           static int compare_anyof_anyofr(int anchored, Arrow *a1, Arrow *a2)
2076             {
2077             unsigned char right[ANYOF_BITMAP_SIZE];
2078              
2079             /* fprintf(stderr, "enter compare_anyof_anyofr(%d\n", anchored); */
2080              
2081             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
2082             assert(OP(a2->rn) == ANYOFR);
2083              
2084 3 50         if (ANYOF_FLAGS(a1->rn) & ANYOF_HAS_EXTRA_RUNTIME_MATCHES)
2085             {
2086 0           return compare_mismatch(anchored, a1, a2);
2087             }
2088              
2089 3 50         if (!convert_anyofr_to_bitmap(a2, right))
2090             {
2091 0           return compare_mismatch(anchored, a1, a2);
2092             }
2093              
2094 3           return compare_bitmaps(anchored, a1, a2, 0, right);
2095             }
2096              
2097 2           static int compare_anyofr_anyofm(int anchored, Arrow *a1, Arrow *a2)
2098             {
2099             unsigned char left[ANYOF_BITMAP_SIZE];
2100             unsigned char right[ANYOF_BITMAP_SIZE];
2101              
2102             assert(OP(a1->rn) == ANYOFR);
2103             assert(OP(a2->rn) == ANYOFM);
2104              
2105 2 50         if (!convert_anyofr_to_bitmap(a1, left))
2106             {
2107 0           return compare_mismatch(anchored, a1, a2);
2108             }
2109              
2110 2 50         if (!convert_anyofm_to_bitmap(a2, right))
2111             {
2112 0           return compare_mismatch(anchored, a1, a2);
2113             }
2114              
2115 2           return compare_bitmaps(anchored, a1, a2, left, right);
2116             }
2117              
2118 77           static int compare_anyofr_anyofr(int anchored, Arrow *a1, Arrow *a2)
2119             {
2120             unsigned char left[ANYOF_BITMAP_SIZE];
2121             unsigned char right[ANYOF_BITMAP_SIZE];
2122              
2123             assert(OP(a1->rn) == ANYOFR);
2124             assert(OP(a2->rn) == ANYOFR);
2125              
2126 77 50         if (!convert_anyofr_to_bitmap(a1, left))
2127             {
2128 0           return compare_mismatch(anchored, a1, a2);
2129             }
2130              
2131 77 50         if (!convert_anyofr_to_bitmap(a2, right))
2132             {
2133 0           return compare_mismatch(anchored, a1, a2);
2134             }
2135              
2136 77           return compare_bitmaps(anchored, a1, a2, left, right);
2137             }
2138              
2139 4           static int compare_anyofm_anyofr(int anchored, Arrow *a1, Arrow *a2)
2140             {
2141             unsigned char left[ANYOF_BITMAP_SIZE];
2142             unsigned char right[ANYOF_BITMAP_SIZE];
2143              
2144             assert(OP(a1->rn) == ANYOFM);
2145             assert(OP(a2->rn) == ANYOFR);
2146              
2147 4 50         if (!convert_anyofm_to_bitmap(a1, left))
2148             {
2149 0           return compare_mismatch(anchored, a1, a2);
2150             }
2151              
2152 4 50         if (!convert_anyofr_to_bitmap(a2, right))
2153             {
2154 0           return compare_mismatch(anchored, a1, a2);
2155             }
2156              
2157 4           return compare_bitmaps(anchored, a1, a2, left, right);
2158             }
2159              
2160 6           static int compare_anyofr_anyof(int anchored, Arrow *a1, Arrow *a2)
2161             {
2162             unsigned char left[ANYOF_BITMAP_SIZE];
2163              
2164             /* fprintf(stderr, "enter compare_anyofr_anyof(%d\n", anchored); */
2165              
2166             assert(OP(a1->rn) == ANYOFR);
2167             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
2168              
2169 6 50         if (!convert_anyofr_to_bitmap(a1, left))
2170             {
2171 0           return compare_mismatch(anchored, a1, a2);
2172             }
2173              
2174 6           return compare_bitmaps(anchored, a1, a2, left, 0);
2175             }
2176              
2177 0           static int compare_anyof_anyofm(int anchored, Arrow *a1, Arrow *a2)
2178             {
2179             unsigned char right[ANYOF_BITMAP_SIZE];
2180              
2181             /* fprintf(stderr, "enter compare_anyof_anyofm(%d\n", anchored); */
2182              
2183             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
2184             assert(OP(a2->rn) == ANYOFM);
2185              
2186 0 0         if (ANYOF_FLAGS(a1->rn) & ANYOF_HAS_EXTRA_RUNTIME_MATCHES)
2187             {
2188 0           return compare_mismatch(anchored, a1, a2);
2189             }
2190              
2191 0 0         if (!convert_anyofm_to_bitmap(a2, right))
2192             {
2193 0           return compare_mismatch(anchored, a1, a2);
2194             }
2195              
2196 0           return compare_bitmaps(anchored, a1, a2, 0, right);
2197             }
2198              
2199 18           static int compare_anyofm_anyof(int anchored, Arrow *a1, Arrow *a2)
2200             {
2201             unsigned char left[ANYOF_BITMAP_SIZE];
2202              
2203             /* fprintf(stderr, "enter compare_anyofm_anyof(%d\n", anchored); */
2204              
2205             assert(OP(a1->rn) == ANYOFM);
2206             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
2207              
2208 18 50         if (!convert_anyofm_to_bitmap(a1, left))
2209             {
2210 0           return compare_mismatch(anchored, a1, a2);
2211             }
2212              
2213 18           return compare_bitmaps(anchored, a1, a2, left, 0);
2214             }
2215              
2216 150           static int compare_anyofm_anyofm(int anchored, Arrow *a1, Arrow *a2)
2217             {
2218             unsigned char left[ANYOF_BITMAP_SIZE];
2219             unsigned char right[ANYOF_BITMAP_SIZE];
2220              
2221             assert(OP(a1->rn) == ANYOFM);
2222             assert(OP(a2->rn) == ANYOFM);
2223              
2224 150 50         if (!convert_anyofm_to_bitmap(a1, left))
2225             {
2226 0           return compare_mismatch(anchored, a1, a2);
2227             }
2228              
2229 150 50         if (!convert_anyofm_to_bitmap(a2, right))
2230             {
2231 0           return compare_mismatch(anchored, a1, a2);
2232             }
2233              
2234 150           return compare_bitmaps(anchored, a1, a2, left, right);
2235             }
2236              
2237 3           static int compare_anyof_nanyofm(int anchored, Arrow *a1, Arrow *a2)
2238             {
2239             int i;
2240             unsigned char right[ANYOF_BITMAP_SIZE];
2241              
2242             /* fprintf(stderr, "enter compare_anyof_nanyofn(%d\n", anchored); */
2243              
2244             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
2245             assert(OP(a2->rn) == NANYOFM);
2246              
2247             /* fprintf(stderr, "left flags = 0x%x\n", FLAGS(a1->rn)); */
2248              
2249 3 50         if ((FLAGS(a1->rn) & ANYOF_HAS_EXTRA_RUNTIME_MATCHES) ||
2250 3 100         ((FLAGS(a1->rn) & ANYOFD_NON_UTF8_MATCHES_ALL_NON_ASCII__shared) &&
2251 1 50         !(FLAGS(a1->rn) & ANYOF_INVERT)))
2252             {
2253 0           return compare_mismatch(anchored, a1, a2);
2254             }
2255              
2256 3 50         if (!convert_anyofm_to_bitmap(a2, right))
2257             {
2258 0           return compare_mismatch(anchored, a1, a2);
2259             }
2260              
2261 99 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
2262             {
2263 96           right[i] = ~right[i];
2264             }
2265              
2266 3           return compare_bitmaps(anchored, a1, a2, 0, right);
2267             }
2268              
2269 1           static int compare_anyofr_nanyofm(int anchored, Arrow *a1, Arrow *a2)
2270             {
2271             int i;
2272             unsigned char left[ANYOF_BITMAP_SIZE];
2273             unsigned char right[ANYOF_BITMAP_SIZE];
2274              
2275             assert(OP(a1->rn) == ANYOFR);
2276             assert(OP(a2->rn) == NANYOFM);
2277              
2278 1 50         if (!convert_anyofr_to_bitmap(a1, left))
2279             {
2280 0           return compare_mismatch(anchored, a1, a2);
2281             }
2282              
2283 1 50         if (!convert_anyofm_to_bitmap(a2, right))
2284             {
2285 0           return compare_mismatch(anchored, a1, a2);
2286             }
2287              
2288 33 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
2289             {
2290 32           right[i] = ~right[i];
2291             }
2292              
2293 1           return compare_bitmaps(anchored, a1, a2, left, right);
2294             }
2295              
2296 3           static int compare_anyofm_nanyofm(int anchored, Arrow *a1, Arrow *a2)
2297             {
2298             int i;
2299             unsigned char left[ANYOF_BITMAP_SIZE];
2300             unsigned char right[ANYOF_BITMAP_SIZE];
2301              
2302             assert(OP(a1->rn) == ANYOFM);
2303             assert(OP(a2->rn) == NANYOFM);
2304              
2305 3 50         if (!convert_anyofm_to_bitmap(a1, left))
2306             {
2307 0           return compare_mismatch(anchored, a1, a2);
2308             }
2309              
2310 3 50         if (!convert_anyofm_to_bitmap(a2, right))
2311             {
2312 0           return compare_mismatch(anchored, a1, a2);
2313             }
2314              
2315 99 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
2316             {
2317 96           right[i] = ~right[i];
2318             }
2319              
2320 3           return compare_bitmaps(anchored, a1, a2, left, right);
2321             }
2322              
2323 41           static int compare_nanyofm_nanyofm(int anchored, Arrow *a1, Arrow *a2)
2324             {
2325             unsigned char left[ANYOF_BITMAP_SIZE];
2326             unsigned char right[ANYOF_BITMAP_SIZE];
2327              
2328             assert(OP(a1->rn) == NANYOFM);
2329             assert(OP(a2->rn) == NANYOFM);
2330              
2331 41 50         if (!convert_anyofm_to_bitmap(a1, left))
2332             {
2333 0           return compare_mismatch(anchored, a1, a2);
2334             }
2335              
2336 41 50         if (!convert_anyofm_to_bitmap(a2, right))
2337             {
2338 0           return compare_mismatch(anchored, a1, a2);
2339             }
2340              
2341 41           return compare_negative_bitmaps(anchored, a1, a2, left, right);
2342             }
2343              
2344             /* compare_bitmaps could replace this method, but when a class
2345             contains just a few characters, it seems more natural to compare
2346             them explicitly */
2347 0           static int compare_short_byte_class(int anchored, Arrow *a1, Arrow *a2,
2348             ByteClass *left)
2349             {
2350             BitFlag bf;
2351             int i;
2352              
2353 0 0         for (i = 0; i < left->expl_size; ++i)
2354             {
2355 0           init_bit_flag(&bf, (unsigned char)left->expl[i]);
2356 0 0         if (!(get_bitmap_byte(a2->rn, bf.offs) & bf.mask))
2357             {
2358 0           return compare_mismatch(anchored, a1, a2);
2359             }
2360             }
2361              
2362 0           return compare_tails(anchored, a1, a2);
2363             }
2364              
2365 0           static int compare_right_full(int anchored, Arrow *a1, Arrow *a2)
2366             {
2367             int i;
2368              
2369 0 0         for (i = 0; i < 16; ++i)
2370             {
2371 0 0         if (!(get_bitmap_byte(a2->rn, i) & 0xff))
2372             {
2373 0           return compare_mismatch(anchored, a1, a2);
2374             }
2375             }
2376              
2377 0           return compare_tails(anchored, a1, a2);
2378             }
2379              
2380 1413           static int compare_posix_posix(int anchored, Arrow *a1, Arrow *a2)
2381             {
2382             U32 m1, m2;
2383             int cr1, cr2;
2384              
2385             /* fprintf(stderr, "enter compare_posix_posix\n"); */
2386              
2387 1413           cr1 = convert_class(a1, &m1);
2388 1413           cr2 = convert_class(a2, &m2);
2389 1413 50         if (!cr1 || !cr2 || (m1 & ~m2))
    50          
    100          
2390             {
2391 262           return compare_mismatch(anchored, a1, a2);
2392             }
2393              
2394 1151           return compare_tails(anchored, a1, a2);
2395             }
2396              
2397 638           static int compare_posix_negative_posix(int anchored, Arrow *a1, Arrow *a2)
2398             {
2399             U32 m1, m2;
2400             int cr1, cr2;
2401              
2402             /* fprintf(stderr, "enter compare_posix_negative_posix\n"); */
2403              
2404 638           cr1 = convert_class(a1, &m1);
2405 638           cr2 = convert_class(a2, &m2);
2406 638 50         if (!cr1 || !cr2)
    50          
2407             {
2408 0           return compare_mismatch(anchored, a1, a2);
2409             }
2410              
2411             /* vertical space is not a strict subset of space, but it does
2412             have space elements, so we have to require space on the right */
2413 638 100         if ((m1 & VERTICAL_SPACE_BLOCK) && !(m2 & VERTICAL_SPACE_BLOCK))
    100          
2414             {
2415 69           m1 |= SPACE_BLOCK;
2416             }
2417              
2418 638 100         if (m1 & m2)
2419             {
2420 169           return compare_mismatch(anchored, a1, a2);
2421             }
2422              
2423 469           return compare_tails(anchored, a1, a2);
2424             }
2425              
2426 475           static int compare_negative_posix_negative_posix(int anchored, Arrow *a1, Arrow *a2)
2427             {
2428             U32 m1, m2;
2429             int cr1, cr2;
2430              
2431             assert((OP(a1->rn) == NPOSIXD) || (OP(a1->rn) == NPOSIXU) ||
2432             (OP(a1->rn) == NPOSIXA));
2433             assert((OP(a2->rn) == NPOSIXD) || (OP(a2->rn) == NPOSIXU) ||
2434             (OP(a2->rn) == NPOSIXA));
2435              
2436             /* fprintf(stderr, "enter compare_negative_posix_negative_posix\n"); */
2437              
2438 475           cr1 = convert_negative_class(a1, &m1);
2439 475           cr2 = convert_negative_class(a2, &m2);
2440 475 50         if (!cr2 || !cr2 || (m1 & ~m2))
    50          
    100          
2441             {
2442 118           return compare_mismatch(anchored, a1, a2);
2443             }
2444              
2445 357           return compare_tails(anchored, a1, a2);
2446             }
2447              
2448 990           static int compare_exact_posix(int anchored, Arrow *a1, Arrow *a2)
2449             {
2450             char *seq;
2451              
2452             assert((OP(a1->rn) == EXACT) || (OP(a1->rn) == EXACTF) ||
2453             (OP(a1->rn) == EXACTFU));
2454             assert((OP(a2->rn) == POSIXD) || (OP(a2->rn) == POSIXU) ||
2455             (OP(a2->rn) == POSIXA));
2456              
2457 990           seq = GET_LITERAL(a1);
2458              
2459 990 100         if (!generic_isCC_A_(*seq, FLAGS(a2->rn)))
2460             {
2461 69           return compare_mismatch(anchored, a1, a2);
2462             }
2463              
2464 921           return compare_tails(anchored, a1, a2);
2465             }
2466              
2467 1           static int compare_exactf_posix(int anchored, Arrow *a1, Arrow *a2)
2468             {
2469             char *seq;
2470             char unf[2];
2471             int i;
2472              
2473             assert((OP(a1->rn) == EXACTF) || (OP(a1->rn) == EXACTFU));
2474             assert(OP(a2->rn) == POSIXD);
2475              
2476 1           seq = GET_LITERAL(a1);
2477 1           init_unfolded(unf, *seq);
2478              
2479 3 100         for (i = 0; i < 2; ++i)
2480             {
2481 2 50         if (!generic_isCC_A_(unf[i], FLAGS(a2->rn)))
2482             {
2483 0           return compare_mismatch(anchored, a1, a2);
2484             }
2485             }
2486              
2487 1           return compare_tails(anchored, a1, a2);
2488             }
2489              
2490 662           static int compare_exact_negative_posix(int anchored, Arrow *a1, Arrow *a2)
2491             {
2492             char *seq;
2493              
2494             assert(OP(a1->rn) == EXACT);
2495             assert((OP(a2->rn) == NPOSIXD) || (OP(a2->rn) == NPOSIXU) ||
2496             (OP(a2->rn) == NPOSIXA));
2497              
2498 662           seq = GET_LITERAL(a1);
2499              
2500 662 100         if (generic_isCC_A_(*seq, FLAGS(a2->rn)))
2501             {
2502 16           return compare_mismatch(anchored, a1, a2);
2503             }
2504              
2505 646           return compare_tails(anchored, a1, a2);
2506             }
2507              
2508 4           static int compare_exactf_negative_posix(int anchored, Arrow *a1, Arrow *a2)
2509             {
2510             char *seq;
2511             char unf[2];
2512             int i;
2513              
2514             assert((OP(a1->rn) == EXACTF) || (OP(a1->rn) == EXACTFU));
2515             assert((OP(a2->rn) == NPOSIXD) || (OP(a2->rn) == NPOSIXU) ||
2516             (OP(a2->rn) == NPOSIXA));
2517              
2518 4           seq = GET_LITERAL(a1);
2519 4           init_unfolded(unf, *seq);
2520              
2521 12 100         for (i = 0; i < 2; ++i)
2522             {
2523 8 50         if (generic_isCC_A_(unf[i], FLAGS(a2->rn)))
2524             {
2525 0           return compare_mismatch(anchored, a1, a2);
2526             }
2527             }
2528              
2529 4           return compare_tails(anchored, a1, a2);
2530             }
2531              
2532 8           static int compare_reg_any_anyof(int anchored, Arrow *a1, Arrow *a2)
2533             {
2534             assert(OP(a1->rn) == REG_ANY);
2535             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
2536              
2537 8           return compare_bitmaps(anchored, a1, a2, ndot.nbitmap, 0);
2538             }
2539              
2540 138           static int compare_posix_anyof(int anchored, Arrow *a1, Arrow *a2)
2541             {
2542             U32 left_block;
2543             unsigned char *b;
2544              
2545             /* fprintf(stderr, "enter compare_posix_anyof\n"); */
2546              
2547             assert((OP(a1->rn) == POSIXD) || (OP(a1->rn) == POSIXU) ||
2548             (OP(a1->rn) == POSIXA));
2549             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
2550              
2551 138 50         if (!convert_class_narrow(a1, &left_block))
2552             {
2553 0           return compare_mismatch(anchored, a1, a2);
2554             }
2555              
2556             /* fprintf(stderr, "right flags = %d\n", FLAGS(a2->rn)); */
2557              
2558 138 100         if (!(FLAGS(a2->rn) & ANYOF_HAS_EXTRA_RUNTIME_MATCHES))
2559             {
2560             U32 right_map;
2561              
2562 66           int cr = convert_map(a2, &right_map);
2563 66 50         if (cr == -1)
2564             {
2565 16           return -1;
2566             }
2567              
2568 66 50         if (!cr || !(right_map & left_block))
    100          
2569             {
2570 16           return compare_mismatch(anchored, a1, a2);
2571             }
2572             }
2573              
2574             /* fprintf(stderr, "left flags = %d\n", FLAGS(a1->rn)); */
2575              
2576 122 50         if (FLAGS(a1->rn) >= SIZEOF_ARRAY(posix_regclass_bitmaps))
2577             {
2578 0           return compare_mismatch(anchored, a1, a2);
2579             }
2580              
2581 122           b = posix_regclass_bitmaps[FLAGS(a1->rn)];
2582 122 50         if (!b)
2583             {
2584 0           return compare_mismatch(anchored, a1, a2);
2585             }
2586              
2587 122           return compare_bitmaps(anchored, a1, a2, b, 0);
2588             }
2589              
2590 55           static int compare_negative_posix_anyof(int anchored, Arrow *a1, Arrow *a2)
2591             {
2592             U32 left_block;
2593             unsigned char *b;
2594              
2595             /* fprintf(stderr, "enter compare_negative_posix_anyof\n"); */
2596              
2597             assert((OP(a1->rn) == NPOSIXD) || (OP(a1->rn) == NPOSIXU) ||
2598             (OP(a1->rn) == NPOSIXA));
2599             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
2600              
2601 55 50         if (!convert_class_narrow(a1, &left_block))
2602             {
2603 0           return compare_mismatch(anchored, a1, a2);
2604             }
2605              
2606             /* fprintf(stderr, "right flags = 0x%x\n", FLAGS(a2->rn)); */
2607              
2608 55           left_block = EVERY_BLOCK & ~left_block;
2609              
2610             /* fprintf(stderr, "left %d -> 0x%x\n", FLAGS(a1->rn), (unsigned)left_block); */
2611              
2612 55 100         if (!(FLAGS(a2->rn) & ANYOF_HAS_EXTRA_RUNTIME_MATCHES))
2613             {
2614             U32 right_map;
2615              
2616 21           int cr = convert_map(a2, &right_map);
2617 21 50         if (cr == -1)
2618             {
2619 3           return -1;
2620             }
2621              
2622 21 100         if (FLAGS(a2->rn) & ANYOF_INVERT)
2623             {
2624 18           right_map = EVERY_BLOCK & ~right_map;
2625             }
2626              
2627             /* fprintf(stderr, "right map = 0x%x\n", (unsigned)right_map); */
2628              
2629 21 50         if (!cr || !(right_map & left_block))
    100          
2630             {
2631 3           return compare_mismatch(anchored, a1, a2);
2632             }
2633             }
2634              
2635 52 50         if (FLAGS(a1->rn) >= SIZEOF_ARRAY(posix_regclass_bitmaps))
2636             {
2637 0           return compare_mismatch(anchored, a1, a2);
2638             }
2639              
2640 52           b = posix_regclass_nbitmaps[FLAGS(a1->rn)];
2641 52 50         if (!b)
2642             {
2643 0           return compare_mismatch(anchored, a1, a2);
2644             }
2645              
2646 52           return compare_bitmaps(anchored, a1, a2, b, 0);
2647             }
2648              
2649 326           static int compare_exact_anyof(int anchored, Arrow *a1, Arrow *a2)
2650             {
2651             BitFlag bf;
2652             char *seq;
2653              
2654             /* fprintf(stderr, "enter compare_exact_anyof(%d, \n", anchored); */
2655              
2656             assert(OP(a1->rn) == EXACT);
2657             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
2658              
2659 326           seq = GET_LITERAL(a1);
2660 326           init_bit_flag(&bf, (unsigned char)(*seq));
2661              
2662 326 100         if (!(get_bitmap_byte(a2->rn, bf.offs) & bf.mask))
2663             {
2664 9           return compare_mismatch(anchored, a1, a2);
2665             }
2666              
2667 317           return compare_tails(anchored, a1, a2);
2668             }
2669              
2670 6           static int compare_exactf_anyof(int anchored, Arrow *a1, Arrow *a2)
2671             {
2672             BitFlag bf;
2673             char *seq;
2674             char unf[2];
2675             int i;
2676              
2677             /* fprintf(stderr, "enter compare_exactf_anyof(%d, \n", anchored); */
2678              
2679             assert((OP(a1->rn) == EXACTF) || (OP(a1->rn) == EXACTFU));
2680             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
2681              
2682 6           seq = GET_LITERAL(a1);
2683 6           init_unfolded(unf, *seq);
2684              
2685 10 50         for (i = 0; i < 2; ++i)
2686             {
2687 10           init_bit_flag(&bf, (unsigned char)unf[i]);
2688 10 100         if (!(get_bitmap_byte(a2->rn, bf.offs) & bf.mask))
2689             {
2690 6           return compare_mismatch(anchored, a1, a2);
2691             }
2692             }
2693              
2694 0           return compare_tails(anchored, a1, a2);
2695             }
2696              
2697 152           static int compare_exact_anyofr(int anchored, Arrow *a1, Arrow *a2)
2698             {
2699             unsigned char *seq;
2700             unsigned char right[ANYOF_BITMAP_SIZE];
2701             BitFlag bf;
2702              
2703             /* fprintf(stderr, "enter compare_exact_anyofr(%d, \n", anchored); */
2704              
2705             assert(OP(a1->rn) == EXACT);
2706             assert(OP(a2->rn) == ANYOFR);
2707              
2708 152           seq = GET_LITERAL(a1);
2709 152           init_bit_flag(&bf, *seq);
2710              
2711 152 50         if (!convert_anyofr_to_bitmap(a2, right))
2712             {
2713 0           return compare_mismatch(anchored, a1, a2);
2714             }
2715              
2716 152 100         if (right[bf.offs] & bf.mask)
2717             {
2718 143           return compare_tails(anchored, a1, a2);
2719             }
2720              
2721 9           return compare_mismatch(anchored, a1, a2);
2722             }
2723              
2724 18           static int compare_exactf_anyofr(int anchored, Arrow *a1, Arrow *a2)
2725             {
2726             char *seq;
2727             int i;
2728             char left[2];
2729             unsigned char right[ANYOF_BITMAP_SIZE];
2730             BitFlag bf;
2731              
2732             /* fprintf(stderr, "enter compare_exactf_anyofr(%d, \n", anchored); */
2733              
2734             assert((OP(a1->rn) == EXACTF) || (OP(a1->rn) == EXACTFU));
2735             assert(OP(a2->rn) == ANYOFR);
2736              
2737 18           seq = GET_LITERAL(a1);
2738 18           init_unfolded(left, *seq);
2739              
2740 18 50         if (!convert_anyofr_to_bitmap(a2, right))
2741             {
2742 0           return compare_mismatch(anchored, a1, a2);
2743             }
2744              
2745 30 50         for (i = 0; i < 2; ++i)
2746             {
2747 30           init_bit_flag(&bf, left[i]);
2748 30 100         if (!(right[bf.offs] & bf.mask))
2749             {
2750 18           return compare_mismatch(anchored, a1, a2);
2751             }
2752             }
2753              
2754 0           return compare_tails(anchored, a1, a2);
2755             }
2756              
2757 155           static int compare_exact_anyofm(int anchored, Arrow *a1, Arrow *a2)
2758             {
2759             unsigned char *seq;
2760             unsigned char right[ANYOF_BITMAP_SIZE];
2761             BitFlag bf;
2762              
2763             /* fprintf(stderr, "enter compare_exact_anyofm(%d, \n", anchored); */
2764              
2765             assert(OP(a1->rn) == EXACT);
2766             assert(OP(a2->rn) == ANYOFM);
2767              
2768 155           seq = GET_LITERAL(a1);
2769 155           init_bit_flag(&bf, *seq);
2770              
2771 155 50         if (!convert_anyofm_to_bitmap(a2, right))
2772             {
2773 0           return compare_mismatch(anchored, a1, a2);
2774             }
2775              
2776 155 100         if (right[bf.offs] & bf.mask)
2777             {
2778 136           return compare_tails(anchored, a1, a2);
2779             }
2780              
2781 19           return compare_mismatch(anchored, a1, a2);
2782             }
2783              
2784 8           static int compare_exactf_anyofm(int anchored, Arrow *a1, Arrow *a2)
2785             {
2786             char *seq;
2787             int i;
2788             char left[2];
2789             unsigned char right[ANYOF_BITMAP_SIZE];
2790             BitFlag bf;
2791              
2792             /* fprintf(stderr, "enter compare_exactf_anyofm(%d, \n", anchored); */
2793              
2794             assert((OP(a1->rn) == EXACTF) || (OP(a1->rn) == EXACTFU));
2795             assert(OP(a2->rn) == ANYOFM);
2796              
2797 8           seq = GET_LITERAL(a1);
2798 8           init_unfolded(left, *seq);
2799              
2800 8 50         if (!convert_anyofm_to_bitmap(a2, right))
2801             {
2802 0           return compare_mismatch(anchored, a1, a2);
2803             }
2804              
2805 22 100         for (i = 0; i < 2; ++i)
2806             {
2807 15           init_bit_flag(&bf, left[i]);
2808 15 100         if (!(right[bf.offs] & bf.mask))
2809             {
2810 1           return compare_mismatch(anchored, a1, a2);
2811             }
2812             }
2813              
2814 7           return compare_tails(anchored, a1, a2);
2815             }
2816              
2817 119           static int compare_exact_nanyofm(int anchored, Arrow *a1, Arrow *a2)
2818             {
2819             char *seq;
2820             unsigned char right[ANYOF_BITMAP_SIZE];
2821             BitFlag bf;
2822              
2823             assert(OP(a1->rn) == EXACT);
2824             assert(OP(a2->rn) == NANYOFM);
2825              
2826 119           seq = GET_LITERAL(a1);
2827 119           init_bit_flag(&bf, *seq);
2828              
2829 119 50         if (!convert_anyofm_to_bitmap(a2, right))
2830             {
2831 0           return compare_mismatch(anchored, a1, a2);
2832             }
2833              
2834 119 50         if (right[bf.offs] & bf.mask)
2835             {
2836 0           return compare_mismatch(anchored, a1, a2);
2837             }
2838              
2839 119           return compare_tails(anchored, a1, a2);
2840             }
2841              
2842 5           static int compare_exactf_nanyofm(int anchored, Arrow *a1, Arrow *a2)
2843             {
2844             char *seq;
2845             int i;
2846             char left[2];
2847             unsigned char right[ANYOF_BITMAP_SIZE];
2848             BitFlag bf;
2849              
2850             assert((OP(a1->rn) == EXACTF) || (OP(a1->rn) == EXACTFU));
2851             assert(OP(a2->rn) == NANYOFM);
2852              
2853 5           seq = GET_LITERAL(a1);
2854 5           init_unfolded(left, *seq);
2855              
2856 5 50         if (!convert_anyofm_to_bitmap(a2, right))
2857             {
2858 0           return compare_mismatch(anchored, a1, a2);
2859             }
2860              
2861 165 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
2862             {
2863 160           right[i] = ~right[i];
2864             }
2865              
2866 15 100         for (i = 0; i < 2; ++i)
2867             {
2868 10           init_bit_flag(&bf, left[i]);
2869 10 50         if (!(right[bf.offs] & bf.mask))
2870             {
2871 0           return compare_mismatch(anchored, a1, a2);
2872             }
2873             }
2874              
2875 5           return compare_tails(anchored, a1, a2);
2876             }
2877              
2878 94           static int compare_posix_nanyofm(int anchored, Arrow *a1, Arrow *a2)
2879             {
2880             int i;
2881             unsigned char *b;
2882             unsigned char right[ANYOF_BITMAP_SIZE];
2883              
2884             assert((OP(a1->rn) == POSIXD) || (OP(a1->rn) == POSIXU) ||
2885             (OP(a1->rn) == POSIXA));
2886             assert(OP(a2->rn) == NANYOFM);
2887              
2888 94 50         if (FLAGS(a1->rn) >= SIZEOF_ARRAY(posix_regclass_bitmaps))
2889             {
2890 0           return compare_mismatch(anchored, a1, a2);
2891             }
2892              
2893 94           b = posix_regclass_bitmaps[FLAGS(a1->rn)];
2894 94 50         if (!b)
2895             {
2896 0           return compare_mismatch(anchored, a1, a2);
2897             }
2898              
2899 94 50         if (!convert_anyofm_to_bitmap(a2, right))
2900             {
2901 0           return compare_mismatch(anchored, a1, a2);
2902             }
2903              
2904 3102 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
2905             {
2906 3008           right[i] = ~right[i];
2907             }
2908              
2909 94           return compare_bitmaps(anchored, a1, a2, b, right);
2910             }
2911              
2912 49           static int compare_negative_posix_nanyofm(int anchored, Arrow *a1, Arrow *a2)
2913             {
2914             int i;
2915             unsigned char *b;
2916             unsigned char right[ANYOF_BITMAP_SIZE];
2917              
2918             assert((OP(a1->rn) == NPOSIXD) || (OP(a1->rn) == NPOSIXU) ||
2919             (OP(a1->rn) == NPOSIXA));
2920             assert(OP(a2->rn) == NANYOFM);
2921              
2922 49 50         if (FLAGS(a1->rn) >= SIZEOF_ARRAY(posix_regclass_bitmaps))
2923             {
2924 0           return compare_mismatch(anchored, a1, a2);
2925             }
2926              
2927             /* positive, because negative bitmaps are compared below */
2928 49           b = posix_regclass_bitmaps[FLAGS(a1->rn)];
2929 49 50         if (!b)
2930             {
2931 0           return compare_mismatch(anchored, a1, a2);
2932             }
2933              
2934 49 50         if (!convert_anyofm_to_bitmap(a2, right))
2935             {
2936 0           return compare_mismatch(anchored, a1, a2);
2937             }
2938              
2939 49           return compare_negative_bitmaps(anchored, a1, a2, b, right);
2940             }
2941              
2942 9           static int compare_exact_lnbreak(int anchored, Arrow *a1, Arrow *a2)
2943             {
2944             char *cur;
2945             char *next;
2946              
2947             assert((OP(a1->rn) == EXACT) || (OP(a1->rn) == EXACTF) ||
2948             (OP(a1->rn) == EXACTFU));
2949             assert(OP(a2->rn) == LNBREAK);
2950              
2951 9           cur = GET_LITERAL(a1);
2952              
2953             /* first, check 2-character newline */
2954 9 100         if ((*cur == '\r') && ((a1->spent + 1) < FLAGS(a1->rn)))
    100          
2955             {
2956             /* we're ignoring the possibility the \n is in a different
2957             node, but that probably doesn't happen */
2958 2           next = (((char *)(a1->rn + 1)) + a1->spent + 1);
2959 2 50         if (*next == '\n')
2960             {
2961 2           ++(a1->spent);
2962 2           return compare_tails(anchored, a1, a2);
2963             }
2964             }
2965              
2966             /* otherwise, check vertical space */
2967 7 100         if (!generic_isCC_A_(*cur, CC_VERTSPACE_))
2968             {
2969 3           return compare_mismatch(anchored, a1, a2);
2970             }
2971              
2972 4           return compare_tails(anchored, a1, a2);
2973             }
2974              
2975 583           static int compare_exact_byte_class(int anchored, Arrow *a1, Arrow *a2,
2976             char *lookup)
2977             {
2978             char *seq;
2979              
2980             assert((OP(a1->rn) == EXACT) || (OP(a1->rn) == EXACTF) ||
2981             (OP(a1->rn) == EXACTFU));
2982              
2983 583           seq = GET_LITERAL(a1);
2984              
2985 583 100         if (!lookup[(unsigned char)(*seq)])
2986             {
2987 31           return compare_mismatch(anchored, a1, a2);
2988             }
2989              
2990 552           return compare_tails(anchored, a1, a2);
2991             }
2992              
2993 35           static int compare_exact_multiline(int anchored, Arrow *a1, Arrow *a2)
2994             {
2995             assert((OP(a1->rn) == EXACT) || (OP(a1->rn) == EXACTF) ||
2996             (OP(a1->rn) == EXACTFU));
2997             assert((OP(a2->rn) == MBOL) || (OP(a2->rn) == MEOL));
2998              
2999 35           return compare_exact_byte_class(anchored, a1, a2,
3000             ndot.lookup);
3001             }
3002              
3003 4           static int compare_sany_anyof(int anchored, Arrow *a1, Arrow *a2)
3004             {
3005             /* fprintf(stderr, "enter compare_sany_anyof\n"); */
3006              
3007             assert(OP(a1->rn) == SANY);
3008             assert((OP(a2->rn) == ANYOF) || (OP(a2->rn) == ANYOFD));
3009              
3010             /* fprintf(stderr, "left flags = 0x%x, right flags = 0x%x\n",
3011             a1->rn->flags, a2->rn->flags); */
3012              
3013 4           return compare_mismatch(anchored, a1, a2);
3014             }
3015              
3016 8           static int compare_anyof_reg_any(int anchored, Arrow *a1, Arrow *a2)
3017             {
3018             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
3019             assert(OP(a2->rn) == REG_ANY);
3020              
3021 8           return compare_bitmaps(anchored, a1, a2, 0, ndot.nbitmap);
3022             }
3023              
3024 8           static int compare_anyofr_reg_any(int anchored, Arrow *a1, Arrow *a2)
3025             {
3026             unsigned char left[ANYOF_BITMAP_SIZE];
3027              
3028             assert(OP(a1->rn) == ANYOFR);
3029             assert(OP(a2->rn) == REG_ANY);
3030              
3031 8 50         if (!convert_anyofr_to_bitmap(a1, left))
3032             {
3033 0           return compare_mismatch(anchored, a1, a2);
3034             }
3035              
3036 8           return compare_bitmaps(anchored, a1, a2, left, ndot.nbitmap);
3037             }
3038              
3039 66           static int compare_anyofm_reg_any(int anchored, Arrow *a1, Arrow *a2)
3040             {
3041             unsigned char left[ANYOF_BITMAP_SIZE];
3042              
3043             assert(OP(a1->rn) == ANYOFM);
3044             assert(OP(a2->rn) == REG_ANY);
3045              
3046 66 50         if (!convert_anyofm_to_bitmap(a1, left))
3047             {
3048 0           return compare_mismatch(anchored, a1, a2);
3049             }
3050              
3051 66           return compare_bitmaps(anchored, a1, a2, left, ndot.nbitmap);
3052             }
3053              
3054 12           static int compare_nanyofm_reg_any(int anchored, Arrow *a1, Arrow *a2)
3055             {
3056             unsigned char left[ANYOF_BITMAP_SIZE];
3057              
3058             assert(OP(a1->rn) == NANYOFM);
3059             assert(OP(a2->rn) == REG_ANY);
3060              
3061 12 50         if (!convert_anyofm_to_bitmap(a1, left))
3062             {
3063 0           return compare_mismatch(anchored, a1, a2);
3064             }
3065              
3066 12           return compare_negative_bitmaps(anchored, a1, a2, left, ndot.bitmap);
3067             }
3068              
3069 2           static int compare_anyof_lnbreak(int anchored, Arrow *a1, Arrow *a2)
3070             {
3071             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
3072             assert(OP(a2->rn) == LNBREAK);
3073              
3074 2           return compare_bitmaps(anchored, a1, a2, 0, vertical_whitespace.bitmap);
3075             }
3076              
3077 548           static int compare_exact_reg_any(int anchored, Arrow *a1, Arrow *a2)
3078             {
3079             assert((OP(a1->rn) == EXACT) || (OP(a1->rn) == EXACTF) ||
3080             (OP(a1->rn) == EXACTFU));
3081             assert(OP(a2->rn) == REG_ANY);
3082              
3083 548           return compare_exact_byte_class(anchored, a1, a2, ndot.nlookup);
3084             }
3085              
3086 6           static int compare_anyof_posix(int anchored, Arrow *a1, Arrow *a2)
3087             {
3088             unsigned char *b;
3089              
3090             /* fprintf(stderr, "enter compare_anyof_posix\n"); */
3091              
3092             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
3093             assert((OP(a2->rn) == POSIXD) || (OP(a2->rn) == POSIXU) ||
3094             (OP(a2->rn) == POSIXA));
3095              
3096 6 50         if (FLAGS(a2->rn) >= SIZEOF_ARRAY(posix_regclass_bitmaps))
3097             {
3098             /* fprintf(stderr, "flags = %d\n", FLAGS(a2->rn)); */
3099 0           return compare_mismatch(anchored, a1, a2);
3100             }
3101              
3102 6           b = posix_regclass_bitmaps[FLAGS(a2->rn)];
3103 6 50         if (!b)
3104             {
3105             /* fprintf(stderr, "no bitmap for flags = %d\n", FLAGS(a2->rn)); */
3106 0           return compare_mismatch(anchored, a1, a2);
3107             }
3108              
3109 6           return compare_bitmaps(anchored, a1, a2, 0, b);
3110             }
3111              
3112 20           static int compare_anyofr_posix(int anchored, Arrow *a1, Arrow *a2)
3113             {
3114             unsigned char *b;
3115             unsigned char left[ANYOF_BITMAP_SIZE];
3116              
3117             /* fprintf(stderr, "enter compare_anyofr_posix\n"); */
3118              
3119             assert(OP(a1->rn) == ANYOFR);
3120             assert((OP(a2->rn) == POSIXD) || (OP(a2->rn) == POSIXU) ||
3121             (OP(a2->rn) == POSIXA));
3122              
3123 20 50         if (!convert_anyofr_to_bitmap(a1, left))
3124             {
3125 0           return compare_mismatch(anchored, a1, a2);
3126             }
3127              
3128 20           b = posix_regclass_bitmaps[FLAGS(a2->rn)];
3129 20 50         if (!b)
3130             {
3131 0           return compare_mismatch(anchored, a1, a2);
3132             }
3133              
3134 20           return compare_bitmaps(anchored, a1, a2, left, b);
3135             }
3136              
3137 101           static int compare_anyofm_posix(int anchored, Arrow *a1, Arrow *a2)
3138             {
3139             unsigned char *b;
3140             unsigned char left[ANYOF_BITMAP_SIZE];
3141              
3142             /* fprintf(stderr, "enter compare_anyofm_posix\n"); */
3143              
3144             assert(OP(a1->rn) == ANYOFM);
3145             assert((OP(a2->rn) == POSIXD) || (OP(a2->rn) == POSIXU) ||
3146             (OP(a2->rn) == POSIXA));
3147              
3148 101 50         if (!convert_anyofm_to_bitmap(a1, left))
3149             {
3150 0           return compare_mismatch(anchored, a1, a2);
3151             }
3152              
3153 101           b = posix_regclass_bitmaps[FLAGS(a2->rn)];
3154 101 50         if (!b)
3155             {
3156 0           return compare_mismatch(anchored, a1, a2);
3157             }
3158              
3159 101           return compare_bitmaps(anchored, a1, a2, left, b);
3160             }
3161              
3162 30           static int compare_nanyofm_posix(int anchored, Arrow *a1, Arrow *a2)
3163             {
3164             unsigned char *b;
3165             unsigned char left[ANYOF_BITMAP_SIZE];
3166              
3167             assert(OP(a1->rn) == NANYOFM);
3168             assert((OP(a2->rn) == POSIXD) || (OP(a2->rn) == POSIXU) ||
3169             (OP(a2->rn) == POSIXA));
3170              
3171 30 50         if (!convert_anyofm_to_bitmap(a1, left))
3172             {
3173 0           return compare_mismatch(anchored, a1, a2);
3174             }
3175              
3176 30           b = posix_regclass_nbitmaps[FLAGS(a2->rn)];
3177 30 50         if (!b)
3178             {
3179 0           return compare_mismatch(anchored, a1, a2);
3180             }
3181              
3182 30           return compare_negative_bitmaps(anchored, a1, a2, left, b);
3183             }
3184              
3185 0           static int compare_anyof_posixa(int anchored, Arrow *a1, Arrow *a2)
3186             {
3187             unsigned char *b;
3188              
3189             /* fprintf(stderr, "enter compare_anyof_posixa\n"); */
3190              
3191             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
3192             assert(OP(a2->rn) == POSIXA);
3193              
3194 0 0         if (ANYOF_FLAGS(a1->rn) & ANYOF_HAS_EXTRA_RUNTIME_MATCHES)
3195             {
3196 0           return compare_mismatch(anchored, a1, a2);
3197             }
3198              
3199 0 0         if (FLAGS(a2->rn) >= SIZEOF_ARRAY(posix_regclass_bitmaps))
3200             {
3201             /* fprintf(stderr, "flags = %d\n", a2->rn->flags); */
3202 0           return compare_mismatch(anchored, a1, a2);
3203             }
3204              
3205 0           b = posix_regclass_bitmaps[FLAGS(a2->rn)];
3206 0 0         if (!b)
3207             {
3208             /* fprintf(stderr, "no bitmap for flags = %d\n", a2->rn->flags); */
3209 0           return compare_mismatch(anchored, a1, a2);
3210             }
3211              
3212 0           return compare_bitmaps(anchored, a1, a2, 0, b);
3213             }
3214              
3215 11           static int compare_anyof_negative_posix(int anchored, Arrow *a1, Arrow *a2)
3216             {
3217             unsigned char *b;
3218              
3219             /* fprintf(stderr, "enter compare_anyof_negative_posix\n"); */
3220              
3221             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
3222             assert((OP(a2->rn) == NPOSIXD) || (OP(a2->rn) == NPOSIXU) ||
3223             (OP(a2->rn) == NPOSIXA));
3224              
3225 11 50         if (FLAGS(a2->rn) >= SIZEOF_ARRAY(posix_regclass_nbitmaps))
3226             {
3227             /* fprintf(stderr, "flags = %d\n", a2->rn->flags); */
3228 0           return compare_mismatch(anchored, a1, a2);
3229             }
3230              
3231 11           b = posix_regclass_nbitmaps[FLAGS(a2->rn)];
3232 11 50         if (!b)
3233             {
3234             /* fprintf(stderr, "no negative bitmap for flags = %d\n", a2->rn->flags); */
3235 0           return compare_mismatch(anchored, a1, a2);
3236             }
3237              
3238 11           return compare_bitmaps(anchored, a1, a2, 0, b);
3239             }
3240              
3241 11           static int compare_anyofr_negative_posix(int anchored, Arrow *a1, Arrow *a2)
3242             {
3243             unsigned char *posix_bitmap;
3244             unsigned char anyof_bitmap[ANYOF_BITMAP_SIZE];
3245              
3246             /* fprintf(stderr, "enter compare_anyofr_negative_posix\n"); */
3247              
3248             assert(OP(a1->rn) == ANYOFR);
3249             assert((OP(a2->rn) == NPOSIXD) || (OP(a2->rn) == NPOSIXU) ||
3250             (OP(a2->rn) == NPOSIXA));
3251              
3252 11 50         if (!convert_anyofr_to_bitmap(a1, anyof_bitmap))
3253             {
3254 0           return compare_mismatch(anchored, a1, a2);
3255             }
3256              
3257 11 50         if (FLAGS(a2->rn) >= SIZEOF_ARRAY(posix_regclass_nbitmaps))
3258             {
3259             /* fprintf(stderr, "flags = %d\n", a2->rn->flags); */
3260 0           return compare_mismatch(anchored, a1, a2);
3261             }
3262              
3263 11           posix_bitmap = posix_regclass_nbitmaps[FLAGS(a2->rn)];
3264 11 50         if (!posix_bitmap)
3265             {
3266             /* fprintf(stderr, "no negative bitmap for flags = %d\n", a2->rn->flags); */
3267 0           return compare_mismatch(anchored, a1, a2);
3268             }
3269              
3270 11           return compare_bitmaps(anchored, a1, a2, anyof_bitmap, posix_bitmap);
3271             }
3272              
3273 73           static int compare_anyofm_negative_posix(int anchored, Arrow *a1, Arrow *a2)
3274             {
3275             unsigned char *posix_bitmap;
3276             unsigned char anyof_bitmap[ANYOF_BITMAP_SIZE];
3277              
3278             /* fprintf(stderr, "enter compare_anyofm_negative_posix\n"); */
3279              
3280             assert(OP(a1->rn) == ANYOFM);
3281             assert((OP(a2->rn) == NPOSIXD) || (OP(a2->rn) == NPOSIXU) ||
3282             (OP(a2->rn) == NPOSIXA));
3283              
3284 73 50         if (!convert_anyofm_to_bitmap(a1, anyof_bitmap))
3285             {
3286 0           return compare_mismatch(anchored, a1, a2);
3287             }
3288              
3289 73 50         if (FLAGS(a2->rn) >= SIZEOF_ARRAY(posix_regclass_nbitmaps))
3290             {
3291             /* fprintf(stderr, "flags = %d\n", a2->rn->flags); */
3292 0           return compare_mismatch(anchored, a1, a2);
3293             }
3294              
3295 73           posix_bitmap = posix_regclass_nbitmaps[FLAGS(a2->rn)];
3296 73 50         if (!posix_bitmap)
3297             {
3298             /* fprintf(stderr, "no negative bitmap for flags = %d\n", a2->rn->flags); */
3299 0           return compare_mismatch(anchored, a1, a2);
3300             }
3301              
3302 73           return compare_bitmaps(anchored, a1, a2, anyof_bitmap, posix_bitmap);
3303             }
3304              
3305 13           static int compare_nanyofm_negative_posix(int anchored, Arrow *a1, Arrow *a2)
3306             {
3307             unsigned char *posix_bitmap;
3308             unsigned char anyof_bitmap[ANYOF_BITMAP_SIZE];
3309              
3310             assert(OP(a1->rn) == NANYOFM);
3311             assert((OP(a2->rn) == NPOSIXD) || (OP(a2->rn) == NPOSIXU) ||
3312             (OP(a2->rn) == NPOSIXA));
3313              
3314 13 50         if (!convert_anyofm_to_bitmap(a1, anyof_bitmap))
3315             {
3316 0           return compare_mismatch(anchored, a1, a2);
3317             }
3318              
3319 13 50         if (FLAGS(a2->rn) >= SIZEOF_ARRAY(posix_regclass_bitmaps))
3320             {
3321 0           return compare_mismatch(anchored, a1, a2);
3322             }
3323              
3324 13           posix_bitmap = posix_regclass_bitmaps[FLAGS(a2->rn)];
3325 13 50         if (!posix_bitmap)
3326             {
3327 0           return compare_mismatch(anchored, a1, a2);
3328             }
3329              
3330 13           return compare_negative_bitmaps(anchored, a1, a2, anyof_bitmap, posix_bitmap);
3331             }
3332              
3333 280           static int compare_posix_reg_any(int anchored, Arrow *a1, Arrow *a2)
3334             {
3335             assert((OP(a1->rn) == POSIXD) || (OP(a1->rn) == POSIXU) ||
3336             (OP(a1->rn) == POSIXA));
3337             assert(OP(a2->rn) == REG_ANY);
3338              
3339 280           U8 flags = FLAGS(a1->rn);
3340 280 50         if (flags >= SIZEOF_ARRAY(newline_posix_regclasses))
3341             {
3342             /* fprintf(stderr, "unknown POSIX character class %d\n", flags); */
3343 0           rc_error = "unknown POSIX character class";
3344 0           return -1;
3345             }
3346              
3347 280 100         if (newline_posix_regclasses[flags])
3348             {
3349 54           return compare_mismatch(anchored, a1, a2);
3350             }
3351              
3352 226           return compare_tails(anchored, a1, a2);
3353             }
3354              
3355 121           static int compare_negative_posix_reg_any(int anchored, Arrow *a1, Arrow *a2)
3356             {
3357             assert((OP(a1->rn) == NPOSIXD) || (OP(a1->rn) == NPOSIXU) ||
3358             (OP(a1->rn) == NPOSIXA));
3359             assert(OP(a2->rn) == REG_ANY);
3360              
3361 121           U8 flags = FLAGS(a1->rn);
3362 121 50         if (flags >= SIZEOF_ARRAY(newline_posix_regclasses))
3363             {
3364 0           rc_error = "unknown negative POSIX character class";
3365 0           return -1;
3366             }
3367              
3368 121 100         if (!newline_posix_regclasses[flags])
3369             {
3370 82           return compare_mismatch(anchored, a1, a2);
3371             }
3372              
3373 39           return compare_tails(anchored, a1, a2);
3374             }
3375              
3376 26           static int compare_posix_lnbreak(int anchored, Arrow *a1, Arrow *a2)
3377             {
3378             assert((OP(a1->rn) == POSIXD) || (OP(a1->rn) == POSIXU) ||
3379             (OP(a1->rn) == POSIXA));
3380             assert(OP(a2->rn) == LNBREAK);
3381              
3382 26 100         if (FLAGS(a1->rn) != CC_VERTSPACE_)
3383             {
3384 8           return compare_mismatch(anchored, a1, a2);
3385             }
3386              
3387 18           return compare_tails(anchored, a1, a2);
3388             }
3389              
3390 0           static int compare_anyof_exact(int anchored, Arrow *a1, Arrow *a2)
3391             {
3392             BitFlag bf;
3393             char *seq;
3394             int i;
3395             unsigned char req;
3396              
3397             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
3398             assert(OP(a2->rn) == EXACT);
3399              
3400 0           seq = GET_LITERAL(a2);
3401 0           init_bit_flag(&bf, *((unsigned char *)seq));
3402              
3403 0 0         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
3404             {
3405 0 0         req = (i != bf.offs) ? 0 : bf.mask;
3406 0 0         if (get_bitmap_byte(a1->rn, i) != req)
3407             {
3408 0           return compare_mismatch(anchored, a1, a2);
3409             }
3410             }
3411              
3412 0           return compare_tails(anchored, a1, a2);
3413             }
3414              
3415 11           static int compare_anyofr_exact(int anchored, Arrow *a1, Arrow *a2)
3416             {
3417             unsigned char left[ANYOF_BITMAP_SIZE];
3418             BitFlag bf;
3419             char *seq;
3420             int i;
3421             unsigned char req;
3422              
3423             assert(OP(a1->rn) == ANYOFR);
3424             assert(OP(a2->rn) == EXACT);
3425              
3426 11 50         if (!convert_anyofr_to_bitmap(a1, left))
3427             {
3428 0           return compare_mismatch(anchored, a1, a2);
3429             }
3430              
3431 11           seq = GET_LITERAL(a2);
3432 11           init_bit_flag(&bf, *((unsigned char *)seq));
3433              
3434 117 50         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
3435             {
3436 117 100         req = (i != bf.offs) ? 0 : bf.mask;
3437 117 100         if (left[i] != req)
3438             {
3439 11           return compare_mismatch(anchored, a1, a2);
3440             }
3441             }
3442              
3443 0           return compare_tails(anchored, a1, a2);
3444             }
3445              
3446 17           static int compare_anyofm_exact(int anchored, Arrow *a1, Arrow *a2)
3447             {
3448             unsigned char left[ANYOF_BITMAP_SIZE];
3449             BitFlag bf;
3450             char *seq;
3451             int i;
3452             unsigned char req;
3453              
3454             assert(OP(a1->rn) == ANYOFM);
3455             assert(OP(a2->rn) == EXACT);
3456              
3457 17 50         if (!convert_anyofm_to_bitmap(a1, left))
3458             {
3459 0           return compare_mismatch(anchored, a1, a2);
3460             }
3461              
3462 17           seq = GET_LITERAL(a2);
3463 17           init_bit_flag(&bf, *((unsigned char *)seq));
3464              
3465 151 50         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
3466             {
3467 151 100         req = (i != bf.offs) ? 0 : bf.mask;
3468 151 100         if (left[i] != req)
3469             {
3470 17           return compare_mismatch(anchored, a1, a2);
3471             }
3472             }
3473              
3474 0           return compare_tails(anchored, a1, a2);
3475             }
3476              
3477 0           static int compare_anyof_exactf(int anchored, Arrow *a1, Arrow *a2)
3478             {
3479             char *seq;
3480             char unf[2];
3481             BitFlag bf[2];
3482             unsigned char right[ANYOF_BITMAP_SIZE];
3483             int i;
3484              
3485             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
3486             assert((OP(a2->rn) == EXACTF) || (OP(a2->rn) == EXACTFU));
3487              
3488 0           seq = GET_LITERAL(a2);
3489 0           init_unfolded(unf, *seq);
3490              
3491 0 0         for (i = 0; i < 2; ++i)
3492             {
3493 0           init_bit_flag(bf + i, (unsigned char)(unf[i]));
3494             }
3495              
3496 0 0         if (bf[0].offs == bf[1].offs)
3497             {
3498 0           bf[0].mask = bf[1].mask = bf[0].mask | bf[1].mask;
3499             }
3500              
3501 0           memset(right, 0, ANYOF_BITMAP_SIZE);
3502 0 0         for (i = 0; i < 2; ++i)
3503             {
3504 0           right[bf[i].offs] = bf[i].mask;
3505             }
3506              
3507 0           return compare_bitmaps(anchored, a1, a2, 0, right);
3508             }
3509              
3510 1           static int compare_anyofr_exactf(int anchored, Arrow *a1, Arrow *a2)
3511             {
3512             char *seq;
3513             int i;
3514             BitFlag bf;
3515             unsigned char left[ANYOF_BITMAP_SIZE];
3516             unsigned char right[ANYOF_BITMAP_SIZE];
3517             char unf[2];
3518              
3519             /* fprintf(stderr, "enter compare_anyofr_exactf(%d, \n", anchored); */
3520              
3521             assert(OP(a1->rn) == ANYOFR);
3522             assert((OP(a2->rn) == EXACTF) || (OP(a2->rn) == EXACTFU));
3523              
3524 1 50         if (!convert_anyofr_to_bitmap(a1, left))
3525             {
3526 0           return compare_mismatch(anchored, a1, a2);
3527             }
3528              
3529 1           seq = GET_LITERAL(a2);
3530 1           init_unfolded(unf, *seq);
3531              
3532 1           memset(right, 0, ANYOF_BITMAP_SIZE);
3533 3 100         for (i = 0; i < 2; ++i)
3534             {
3535 2           init_bit_flag(&bf, unf[i]);
3536 2           right[bf.offs] = bf.mask;
3537             }
3538              
3539 1           return compare_bitmaps(anchored, a1, a2, left, right);
3540             }
3541              
3542 1           static int compare_anyofm_exactf(int anchored, Arrow *a1, Arrow *a2)
3543             {
3544             char *seq;
3545             int i;
3546             BitFlag bf;
3547             unsigned char left[ANYOF_BITMAP_SIZE];
3548             unsigned char right[ANYOF_BITMAP_SIZE];
3549             char unf[2];
3550              
3551             /* fprintf(stderr, "enter compare_anyofm_exactf(%d, \n", anchored); */
3552              
3553             assert(OP(a1->rn) == ANYOFM);
3554             assert((OP(a2->rn) == EXACTF) || (OP(a2->rn) == EXACTFU));
3555              
3556 1 50         if (!convert_anyofm_to_bitmap(a1, left))
3557             {
3558 0           return compare_mismatch(anchored, a1, a2);
3559             }
3560              
3561 1           seq = GET_LITERAL(a2);
3562 1           init_unfolded(unf, *seq);
3563              
3564 1           memset(right, 0, ANYOF_BITMAP_SIZE);
3565 3 100         for (i = 0; i < 2; ++i)
3566             {
3567 2           init_bit_flag(&bf, unf[i]);
3568 2           right[bf.offs] = bf.mask;
3569             }
3570              
3571 1           return compare_bitmaps(anchored, a1, a2, left, right);
3572             }
3573              
3574 6861           static int compare_exact_exact(int anchored, Arrow *a1, Arrow *a2)
3575             {
3576             char *q1, *q2;
3577              
3578 6861           q1 = GET_LITERAL(a1);
3579 6861           q2 = GET_LITERAL(a2);
3580              
3581             /* fprintf(stderr, "enter compare_exact_exact(%d, '%c', '%c')\n", anchored,
3582             *q1, *q2); */
3583              
3584 6861 100         if (*q1 != *q2)
3585             {
3586 2577           return compare_mismatch(anchored, a1, a2);
3587             }
3588              
3589 4284           return compare_tails(anchored, a1, a2);
3590             }
3591              
3592 18           static int compare_exact_exactf(int anchored, Arrow *a1, Arrow *a2)
3593             {
3594             char *q1, *q2;
3595             char unf[2];
3596              
3597             assert(OP(a1->rn) == EXACT);
3598             assert((OP(a2->rn) == EXACTF) || (OP(a2->rn) == EXACTFU));
3599              
3600 18           q1 = GET_LITERAL(a1);
3601 18           q2 = GET_LITERAL(a2);
3602 18           init_unfolded(unf, *q2);
3603              
3604 18 100         if ((*q1 != unf[0]) && (*q1 != unf[1]))
    100          
3605             {
3606 5           return compare_mismatch(anchored, a1, a2);
3607             }
3608              
3609 13           return compare_tails(anchored, a1, a2);
3610             }
3611              
3612 14           static int compare_exactf_exact(int anchored, Arrow *a1, Arrow *a2)
3613             {
3614             char *q1, *q2;
3615             char unf[2];
3616              
3617             assert((OP(a1->rn) == EXACTF) || (OP(a1->rn) == EXACTFU));
3618             assert(OP(a2->rn) == EXACT);
3619              
3620 14           q1 = GET_LITERAL(a1);
3621 14           init_unfolded(unf, *q1);
3622 14           q2 = GET_LITERAL(a2);
3623              
3624 14 100         if ((unf[0] != *q2) || (unf[1] != *q2))
    50          
3625             {
3626 14           return compare_mismatch(anchored, a1, a2);
3627             }
3628              
3629 0           return compare_tails(anchored, a1, a2);
3630             }
3631              
3632 429           static int compare_exactf_exactf(int anchored, Arrow *a1, Arrow *a2)
3633             {
3634             char *q1, *q2;
3635             char l1, l2;
3636              
3637             assert((OP(a1->rn) == EXACTF) || (OP(a1->rn) == EXACTFU));
3638             assert((OP(a2->rn) == EXACTF) || (OP(a2->rn) == EXACTFU));
3639              
3640 429           q1 = GET_LITERAL(a1);
3641 429           q2 = GET_LITERAL(a2);
3642              
3643 429 50         l1 = TOLOWER(*q1);
    50          
3644 429 50         l2 = TOLOWER(*q2);
    50          
3645              
3646 429 100         if (l1 != l2)
3647             {
3648 54           return compare_mismatch(anchored, a1, a2);
3649             }
3650              
3651 375           return compare_tails(anchored, a1, a2);
3652             }
3653              
3654 617           static int compare_left_branch(int anchored, Arrow *a1, Arrow *a2)
3655             {
3656             int rv, tsz;
3657             regnode *p1;
3658             Arrow left, right;
3659              
3660             /* fprintf(stderr, "enter compare_left_branch\n"); */
3661              
3662             assert(OP(a1->rn) == BRANCH);
3663              
3664             /* origins stay the same throughout the cycle */
3665 617           left.origin = a1->origin;
3666 617           right.origin = a2->origin;
3667 617           p1 = a1->rn;
3668 1837 100         while (OP(p1) == BRANCH)
3669             {
3670 1257 50         if (NEXT_OFF(p1) == 0)
3671             {
3672 0           rc_error = "Branch with zero offset";
3673 0           return -1;
3674             }
3675              
3676 1257           left.rn = p1 + RC_BRANCH_REGNODE_SIZE;
3677 1257           left.spent = 0;
3678              
3679 1257           right.rn = a2->rn;
3680 1257           right.spent = a2->spent;
3681              
3682 1257           rv = compare(anchored, &left, &right);
3683             /* fprintf(stderr, "rv = %d\n", rv); */
3684              
3685 1257 50         if (rv < 0)
3686             {
3687 0           return rv;
3688             }
3689              
3690 1257 100         if (!rv)
3691             {
3692             /* fprintf(stderr, "compare_left_branch doesn't match\n"); */
3693 37           return compare_mismatch(anchored, a1, a2);
3694             }
3695              
3696 1220           p1 += NEXT_OFF(p1);
3697             }
3698              
3699 580           a1->rn = p1;
3700 580           a1->spent = 0;
3701              
3702 580           tsz = get_size(a2->rn);
3703 580 50         if (tsz <= 0)
3704             {
3705 0           return -1;
3706             }
3707              
3708 580           a2->rn += tsz - 1;
3709 580           a2->spent = 0;
3710              
3711 580           return 1;
3712             }
3713              
3714 38           static int compare_set(int anchored, Arrow *a1, Arrow *a2, unsigned char *b1)
3715             {
3716             regnode *alt, *t1;
3717             Arrow left, right;
3718             int i, j, power, rv, sz, offs;
3719             unsigned char loc;
3720              
3721 38 50         offs = GET_OFFSET(a1->rn);
3722 38 50         if (offs <= 0)
3723             {
3724 0           return -1;
3725             }
3726              
3727 38           t1 = a1->rn + offs;
3728 38           sz = get_size(t1);
3729 38 50         if (sz < 0)
3730             {
3731 0           return sz;
3732             }
3733              
3734 38           alt = (regnode *)malloc(sizeof(regnode) * (2 + sz));
3735 38 50         if (!alt)
3736             {
3737 0           rc_error = "Couldn't allocate memory for alternative copy";
3738 0           return -1;
3739             }
3740              
3741 38           FLAGS(alt) = 1;
3742 38           OP(alt) = EXACT;
3743 38           NEXT_OFF(alt) = 2;
3744 38           memcpy(alt + 2, t1, sizeof(regnode) * sz);
3745              
3746 38           left.origin = a1->origin;
3747 38           right.origin = a2->origin;
3748 38           right.rn = 0;
3749              
3750 1234 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
3751             {
3752 1197 100         loc = b1 ? b1[i] : get_bitmap_byte(a1->rn, i);
3753 1197 100         if ((i >= 16) && loc)
    50          
3754             {
3755 0           free(alt);
3756 0           return compare_mismatch(anchored, a1, a2);
3757             }
3758              
3759 1197           power = 1;
3760 10768 100         for (j = 0; j < 8; ++j)
3761             {
3762 9572 100         if (loc & power)
3763             {
3764 256           FLAGS(alt + 1) = 8 * i + j;
3765 256           left.rn = alt;
3766 256           left.spent = 0;
3767              
3768 256           right.rn = a2->rn;
3769 256           right.spent = a2->spent;
3770              
3771 256           rv = compare_right_branch(anchored, &left, &right);
3772 256 50         if (rv < 0)
3773             {
3774 0           free(alt);
3775 0           return rv;
3776             }
3777              
3778 256 100         if (!rv)
3779             {
3780 1           free(alt);
3781 1           return compare_mismatch(anchored, a1, a2);
3782             }
3783             }
3784              
3785 9571           power *= 2;
3786             }
3787             }
3788              
3789 37           free(alt);
3790              
3791 37 50         if (!right.rn)
3792             {
3793 0           rc_error = "Empty mask not supported";
3794 0           return -1;
3795             }
3796              
3797 37           a1->rn = t1 + sz - 1;
3798             assert(OP(a1->rn) == END);
3799 37           a1->spent = 0;
3800              
3801 37           a2->rn = right.rn;
3802 37           a2->spent = right.spent;
3803              
3804 37           return 1;
3805             }
3806              
3807 4           static int compare_anyof_branch(int anchored, Arrow *a1, Arrow *a2)
3808             {
3809             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
3810             assert(OP(a2->rn) == BRANCH);
3811              
3812 4           return compare_set(anchored, a1, a2, 0);
3813             }
3814              
3815 14           static int compare_anyofr_branch(int anchored, Arrow *a1, Arrow *a2)
3816             {
3817             unsigned char left[ANYOF_BITMAP_SIZE];
3818              
3819             assert(OP(a1->rn) == ANYOFR);
3820             assert(OP(a2->rn) == BRANCH);
3821              
3822 14 50         if (!convert_anyofr_to_bitmap(a1, left))
3823             {
3824 0           return compare_mismatch(anchored, a1, a2);
3825             }
3826              
3827 14           return compare_set(anchored, a1, a2, left);
3828             }
3829              
3830 20           static int compare_anyofm_branch(int anchored, Arrow *a1, Arrow *a2)
3831             {
3832             unsigned char left[ANYOF_BITMAP_SIZE];
3833              
3834             assert(OP(a1->rn) == ANYOFM);
3835             assert(OP(a2->rn) == BRANCH);
3836              
3837 20 50         if (!convert_anyofm_to_bitmap(a1, left))
3838             {
3839 0           return compare_mismatch(anchored, a1, a2);
3840             }
3841              
3842 20           return compare_set(anchored, a1, a2, left);
3843             }
3844              
3845 1473           static int compare_right_branch(int anchored, Arrow *a1, Arrow *a2)
3846             {
3847             int rv;
3848             regnode *p2;
3849             Arrow left, right;
3850              
3851             /* fprintf(stderr, "enter compare_right_branch\n"); */
3852              
3853             assert(OP(a2->rn) == BRANCH);
3854              
3855             /* origins stay the same throughout the cycle */
3856 1473           left.origin = a1->origin;
3857 1473           right.origin = a2->origin;
3858 1473           p2 = a2->rn;
3859 1473           rv = 0;
3860 3852 100         while ((OP(p2) == BRANCH) && !rv)
    100          
3861             {
3862             /* fprintf(stderr, "p2->type = %d\n", p2->type); */
3863              
3864 2379           left.rn = a1->rn;
3865 2379           left.spent = a1->spent;
3866              
3867 2379 50         if (NEXT_OFF(p2) == 0)
3868             {
3869 0           rc_error = "Branch with offset zero";
3870 0           return -1;
3871             }
3872              
3873 2379           right.rn = p2 + RC_BRANCH_REGNODE_SIZE;
3874 2379           right.spent = 0;
3875              
3876 2379           rv = compare(anchored, &left, &right);
3877             /* fprintf(stderr, "got %d\n", rv); */
3878              
3879 2379           p2 += NEXT_OFF(p2);
3880             }
3881              
3882 1473 50         if (rv < 0)
3883             {
3884 0           return rv;
3885             }
3886              
3887 1473 100         if (!rv)
3888             {
3889 134           return compare_mismatch(anchored, a1, a2);
3890             }
3891              
3892 1339           a1->rn = left.rn;
3893 1339           a1->spent = left.spent;
3894              
3895 1339           a2->rn = right.rn;
3896 1339           a2->spent = right.spent;
3897              
3898 1339           return 1;
3899             }
3900              
3901 414           static int compare_right_star(int anchored, Arrow *a1, Arrow *a2)
3902             {
3903             regnode *p2;
3904             Arrow left, right;
3905             int sz, rv, offs;
3906              
3907             /* fprintf(stderr, "enter compare_right_star\n"); */
3908              
3909 414           p2 = a2->rn;
3910             assert(OP(p2) == STAR);
3911              
3912 414           sz = get_size(p2);
3913 414 50         if (sz < 0)
3914             {
3915 0           return sz;
3916             }
3917              
3918 414           left.origin = a1->origin;
3919 414           left.rn = a1->rn;
3920 414           left.spent = a1->spent;
3921              
3922 414 50         offs = GET_OFFSET(p2);
3923 414 50         if (offs <= 0)
3924             {
3925 0           return -1;
3926             }
3927              
3928 414           right.origin = a2->origin;
3929 414           right.rn = p2 + offs;
3930 414           right.spent = 0;
3931              
3932 414           rv = compare(anchored, &left, &right);
3933 414 50         if (rv < 0)
3934             {
3935 0           return rv;
3936             }
3937              
3938 414 100         if (rv == 0)
3939             {
3940 9           right.rn = p2 + 1;
3941 9           right.spent = 0;
3942              
3943 9           rv = compare(anchored, a1, &right);
3944 9 50         if (rv < 0)
3945             {
3946 0           return rv;
3947             }
3948              
3949 9 100         if (!rv)
3950             {
3951 4           return compare_mismatch(anchored, a1, a2);
3952             }
3953              
3954 5           right.rn = p2;
3955 5           right.spent = 0;
3956              
3957 5 50         if (!anchored)
3958             {
3959 0           rv = compare_right_star(1, a1, &right);
3960             }
3961             }
3962              
3963 410 50         if (rv <= 0)
3964             {
3965 0           return rv;
3966             }
3967              
3968 410           a2->rn += sz - 1;
3969             assert(OP(a2->rn) == END);
3970 410           a2->spent = 0;
3971              
3972 410           return rv;
3973             }
3974              
3975 139           static int compare_plus_plus(int anchored, Arrow *a1, Arrow *a2)
3976             {
3977             regnode *p1, *p2;
3978             Arrow left, right;
3979             int rv, offs;
3980              
3981 139           p1 = a1->rn;
3982             assert(OP(p1) == PLUS);
3983 139           p2 = a2->rn;
3984             assert(OP(p2) == PLUS);
3985              
3986 139           left.origin = a1->origin;
3987 139           left.rn = p1 + 1;
3988 139           left.spent = 0;
3989              
3990 139           right.origin = a2->origin;
3991 139           right.rn = p2 + 1;
3992 139           right.spent = 0;
3993              
3994 139           rv = compare(1, &left, &right);
3995 139 100         if (rv)
3996             {
3997 126           return rv;
3998             }
3999              
4000 13 50         offs = GET_OFFSET(p1);
4001             /* fprintf(stderr, "offs = %d\n", offs); */
4002 13 50         if (offs <= 0)
4003             {
4004 0           return -1;
4005             }
4006              
4007 13           left.origin = a1->origin;
4008 13           left.rn = p1 + offs;
4009 13           left.spent = 0;
4010 13           return compare(1, &left, a2);
4011             }
4012              
4013 156           static int compare_repeat_star(int anchored, Arrow *a1, Arrow *a2)
4014             {
4015             regnode *p1, *p2;
4016             Arrow left, right;
4017             int rv, offs;
4018              
4019 156           p1 = a1->rn;
4020             assert((OP(p1) == PLUS) || (OP(p1) == STAR));
4021 156           p2 = a2->rn;
4022             assert(OP(p2) == STAR);
4023             /* fprintf(stderr, "enter compare_repeat_star(%d, %d, %d)\n",
4024             anchored, p1->type, p2->type); */
4025              
4026 156           left.origin = a1->origin;
4027 156           left.rn = p1 + 1;
4028 156           left.spent = 0;
4029              
4030 156           right.origin = a2->origin;
4031 156           right.rn = p2 + 1;
4032 156           right.spent = 0;
4033              
4034 156           rv = compare(1, &left, &right);
4035             /* fprintf(stderr, "inclusive compare returned %d\n", rv); */
4036 156 100         if (rv)
4037             {
4038 140           return rv;
4039             }
4040              
4041 16 50         offs = GET_OFFSET(p2);
4042             /* fprintf(stderr, "offs = %d\n", offs); */
4043 16 50         if (offs <= 0)
4044             {
4045 0           return -1;
4046             }
4047              
4048 16           right.origin = a2->origin;
4049 16           right.rn = p2 + offs;
4050 16           right.spent = 0;
4051 16           return compare(1, &left, &right);
4052             }
4053              
4054 310           static int compare_right_curly_from_zero(int anchored, Arrow *a1, Arrow *a2)
4055             {
4056             regnode *p2, *alt;
4057             CurlyCount *cnt;
4058             Arrow left, right;
4059             int sz, rv, offs;
4060              
4061 310           p2 = a2->rn;
4062              
4063 310           sz = get_size(p2);
4064 310 50         if (sz < 0)
4065             {
4066 0           return sz;
4067             }
4068              
4069 310           left.origin = a1->origin;
4070 310           left.rn = a1->rn;
4071 310           left.spent = a1->spent;
4072              
4073 310 50         offs = GET_OFFSET(p2);
4074 310 50         if (offs <= 0)
4075             {
4076 0           return -1;
4077             }
4078              
4079 310           right.origin = a2->origin;
4080 310           right.rn = p2 + offs;
4081 310           right.spent = 0;
4082              
4083 310           rv = compare(anchored, &left, &right);
4084 310 50         if (rv < 0)
4085             {
4086 0           return rv;
4087             }
4088              
4089 310 100         if (rv == 0)
4090             {
4091 4           alt = alloc_alt(p2, sz);
4092 4 50         if (!alt)
4093             {
4094 0           return -1;
4095             }
4096              
4097 4           right.rn = alt + RC_CURLY_REGNODE_SIZE;
4098 4           right.spent = 0;
4099              
4100 4           rv = compare(anchored, a1, &right);
4101 4 50         if (rv < 0)
4102             {
4103 0           free(alt);
4104 0           return rv;
4105             }
4106              
4107 4 100         if (!rv)
4108             {
4109 2           free(alt);
4110 2           return compare_mismatch(anchored, a1, a2);
4111             }
4112              
4113 2           cnt = (CurlyCount *)(alt + 1);
4114 2 50         if (cnt[1] < INFINITE_COUNT)
4115             {
4116 2           --cnt[1];
4117             }
4118              
4119 2 100         if ((cnt[1] > 0) && !anchored)
    50          
4120             {
4121 0           right.rn = alt;
4122 0           right.spent = 0;
4123              
4124 0           rv = compare_right_curly_from_zero(1, a1, &right);
4125             }
4126             else
4127             {
4128 2           rv = 1;
4129             }
4130              
4131 2           free(alt);
4132             }
4133              
4134 308 50         if (rv <= 0)
4135             {
4136 0           return rv;
4137             }
4138              
4139 308           a2->rn += sz - 1;
4140             assert(OP(a2->rn) == END);
4141 308           a2->spent = 0;
4142              
4143 308           return rv;
4144             }
4145              
4146 505           static int compare_left_plus(int anchored, Arrow *a1, Arrow *a2)
4147             {
4148             regnode *p1, *alt, *q;
4149             Arrow left, right;
4150             int sz, rv, offs, end_offs;
4151             unsigned char orig_type;
4152              
4153 505           p1 = a1->rn;
4154             assert(OP(p1) == PLUS);
4155              
4156 505           sz = get_size(p1);
4157 505 50         if (sz < 0)
4158             {
4159 0           return -1;
4160             }
4161              
4162 505 50         if (sz < 2)
4163             {
4164 0           rc_error = "Left plus offset too small";
4165 0           return -1;
4166             }
4167              
4168 505           alt = alloc_alt(p1 + 1, sz - 1);
4169 505 50         if (!alt)
4170             {
4171 0           return -1;
4172             }
4173              
4174 505 100         if (anchored)
4175             {
4176 14           offs = get_jump_offset(p1);
4177 14 50         if (offs <= 0)
4178             {
4179 0           return -1;
4180             }
4181              
4182 14           q = p1 + offs;
4183 14 100         if (OP(q) != END)
4184             {
4185             /* repeat with a tail after it can be more strict than a
4186             fixed-length match only if the tail is at least as
4187             strict as the repeated regexp */
4188 6           left.origin = a1->origin;
4189 6           left.rn = q;
4190 6           left.spent = 0;
4191              
4192 6           end_offs = offs - 1;
4193 6           orig_type = OP(alt + end_offs);
4194 6           OP(alt + end_offs) = END;
4195              
4196 6           right.origin = a2->origin;
4197 6           right.rn = alt;
4198 6           right.spent = 0;
4199              
4200             /* fprintf(stderr, "comparing %d to %d\n", left.rn->type,
4201             right.rn->type); */
4202 6           rv = compare(1, &left, &right);
4203             /* fprintf(stderr, "compare returned %d\n", rv); */
4204 6 100         if (rv <= 0)
4205             {
4206 4           free(alt);
4207 4           return rv;
4208             }
4209              
4210 2           OP(alt + end_offs) = orig_type;
4211             }
4212             }
4213              
4214 501           left.origin = a1->origin;
4215 501           left.rn = alt;
4216 501           left.spent = 0;
4217 501           rv = compare(anchored, &left, a2);
4218 501           free(alt);
4219 501           return rv;
4220             }
4221              
4222 275           static int compare_right_plus(int anchored, Arrow *a1, Arrow *a2)
4223             {
4224             regnode *p2;
4225             Arrow right;
4226             int sz, rv;
4227              
4228 275           p2 = a2->rn;
4229             assert(OP(p2) == PLUS);
4230              
4231             /* fprintf(stderr, "enter compare_right_plus\n"); */
4232              
4233 275           sz = get_size(p2);
4234 275 50         if (sz < 0)
4235             {
4236 0           return -1;
4237             }
4238              
4239 275 50         if (sz < 2)
4240             {
4241 0           rc_error = "Plus offset too small";
4242 0           return -1;
4243             }
4244              
4245             /* fprintf(stderr, "sz = %d\n", sz); */
4246              
4247 275           right.origin = a2->origin;
4248 275           right.rn = p2 + 1;
4249 275           right.spent = 0;
4250              
4251 275           rv = compare(anchored, a1, &right);
4252              
4253 275 50         if (rv < 0)
4254             {
4255 0           return rv;
4256             }
4257              
4258 275 100         if (!rv)
4259             {
4260 24           return compare_mismatch(anchored, a1, a2);
4261             }
4262              
4263 251           a2->rn += sz - 1;
4264             assert(OP(a2->rn) == END);
4265 251           a2->spent = 0;
4266              
4267 251           return rv;
4268             }
4269              
4270 1271           static int compare_next(int anchored, Arrow *a1, Arrow *a2)
4271             {
4272 1271 50         if (bump_regular(a2) <= 0)
4273             {
4274 0           return -1;
4275             }
4276              
4277 1271           return compare(anchored, a1, a2);
4278             }
4279              
4280 21           static int compare_curly_plus(int anchored, Arrow *a1, Arrow *a2)
4281             {
4282             regnode *p1, *p2;
4283             Arrow left, right;
4284             CurlyCount *cnt;
4285              
4286 21           p1 = a1->rn;
4287             assert((OP(p1) == CURLY) || (OP(p1) == CURLYM) ||
4288             (OP(p1) == CURLYX));
4289 21           p2 = a2->rn;
4290             assert(OP(p2) == PLUS);
4291              
4292 21           cnt = (CurlyCount *)(p1 + 1);
4293              
4294 21 50         if (!cnt[0])
4295             {
4296 0           return compare_mismatch(anchored, a1, a2);
4297             }
4298              
4299 21           left.origin = a1->origin;
4300 21           left.rn = p1 + RC_CURLY_REGNODE_SIZE;
4301 21           left.spent = 0;
4302              
4303 21           right.origin = a2->origin;
4304 21           right.rn = p2 + 1;
4305 21           right.spent = 0;
4306              
4307 21 100         if (cnt[0] > 1)
4308             {
4309 9           anchored = 1;
4310             }
4311              
4312 21           return compare(anchored, &left, &right);
4313             }
4314              
4315 30           static int compare_curly_star(int anchored, Arrow *a1, Arrow *a2)
4316             {
4317             regnode *p1, *p2;
4318             Arrow left, right;
4319             int rv;
4320              
4321 30           p1 = a1->rn;
4322             assert((OP(p1) == CURLY) || (OP(p1) == CURLYM) ||
4323             (OP(p1) == CURLYX));
4324 30           p2 = a2->rn;
4325             assert(OP(p2) == STAR);
4326              
4327 30           left.origin = a1->origin;
4328 30           left.rn = p1 + RC_CURLY_REGNODE_SIZE;
4329 30           left.spent = 0;
4330              
4331 30           right.origin = a2->origin;
4332 30           right.rn = p2 + 1;
4333 30           right.spent = 0;
4334              
4335 30           rv = compare(1, &left, &right);
4336 30 100         if (!rv)
4337             {
4338 11           rv = compare_next(anchored, a1, a2);
4339             }
4340              
4341 30           return rv;
4342             }
4343              
4344 41           static int compare_plus_curly(int anchored, Arrow *a1, Arrow *a2)
4345             {
4346             regnode *p1, *p2, *e2;
4347             Arrow left, right;
4348             CurlyCount *cnt;
4349             int rv, offs;
4350              
4351 41           p1 = a1->rn;
4352             assert(OP(p1) == PLUS);
4353 41           p2 = a2->rn;
4354             assert((OP(p2) == CURLY) || (OP(p2) == CURLYM) ||
4355             (OP(p2) == CURLYX));
4356              
4357 41           cnt = (CurlyCount *)(p2 + 1);
4358              
4359 41 100         if (cnt[0] > 1) /* FIXME: fails '(?:aa)+' => 'a{2,}' */
4360             {
4361 2           return compare_mismatch(anchored, a1, a2);
4362             }
4363              
4364 39           left.origin = a1->origin;
4365 39           left.rn = p1 + 1;
4366 39           left.spent = 0;
4367              
4368 39 100         if (cnt[1] != INFINITE_COUNT)
4369             {
4370 35           offs = get_jump_offset(p2);
4371 35 50         if (offs <= 0)
4372             {
4373 0           return -1;
4374             }
4375              
4376 35           e2 = p2 + offs;
4377 35 50         if (OP(e2) != END)
4378             {
4379 0           return compare_mismatch(anchored, a1, a2);
4380             }
4381             }
4382              
4383 39           right.origin = a2->origin;
4384 39           right.rn = p2 + RC_CURLY_REGNODE_SIZE;
4385 39           right.spent = 0;
4386              
4387 39           rv = compare(anchored, &left, &right);
4388 39 50         return (!rv && !cnt[0]) ? compare_next(anchored, a1, a2) : rv;
    0          
4389             }
4390              
4391 12           static int compare_suspend_curly(int anchored, Arrow *a1, Arrow *a2)
4392             {
4393             assert(OP(a1->rn) == SUSPEND);
4394             assert(!a1->spent);
4395              
4396 12           a1->rn += 2;
4397              
4398 12           return compare(1, a1, a2);
4399             }
4400              
4401 379           static void dec_curly_counts(CurlyCount *altcnt)
4402             {
4403 379           --altcnt[0];
4404 379 100         if (altcnt[1] < INFINITE_COUNT)
4405             {
4406 159           --altcnt[1];
4407             }
4408 379           }
4409              
4410 650           static int compare_left_curly(int anchored, Arrow *a1, Arrow *a2)
4411             {
4412             regnode *p1, *alt, *q;
4413             Arrow left, right;
4414             int sz, rv, offs, end_offs;
4415             CurlyCount *cnt;
4416              
4417             /* fprintf(stderr, "enter compare_left_curly(%d, %d, %d)\n", anchored,
4418             OP(a1->rn), OP(a2->rn)); */
4419              
4420 650           p1 = a1->rn;
4421             assert((OP(p1) == CURLY) || (OP(p1) == CURLYM) ||
4422             (OP(p1) == CURLYX));
4423              
4424 650           cnt = (CurlyCount *)(p1 + 1);
4425 650 100         if (!cnt[0])
4426             {
4427             /* fprintf(stderr, "curly from 0\n"); */
4428 8           return compare_mismatch(anchored, a1, a2);
4429             }
4430              
4431 642           sz = get_size(p1);
4432 642 50         if (sz < 0)
4433             {
4434 0           return -1;
4435             }
4436              
4437 642 50         if (sz <= RC_CURLY_REGNODE_SIZE)
4438             {
4439 0           rc_error = "Left curly offset too small";
4440 0           return -1;
4441             }
4442              
4443 642 100         if (cnt[0] > 1)
4444             {
4445             /* fprintf(stderr, "curly with non-trivial repeat count\n"); */
4446              
4447 342 50         offs = GET_OFFSET(p1);
4448 342 50         if (offs < 0)
4449             {
4450 0           return -1;
4451             }
4452              
4453 342 50         if (offs <= RC_CURLY_REGNODE_SIZE)
4454             {
4455 0           rc_error = "Left curly offset is too small";
4456 0           return -1;
4457             }
4458              
4459 342           alt = (regnode *)malloc(sizeof(regnode) * (offs - RC_CURLY_REGNODE_SIZE + sz));
4460 342 50         if (!alt)
4461             {
4462 0           rc_error = "Could not allocate memory for unrolled curly";
4463 0           return -1;
4464             }
4465              
4466 342           memcpy(alt, p1 + RC_CURLY_REGNODE_SIZE, (offs - RC_CURLY_REGNODE_SIZE) * sizeof(regnode));
4467 342           memcpy(alt + offs - RC_CURLY_REGNODE_SIZE, p1, sz * sizeof(regnode));
4468              
4469 342           dec_curly_counts((CurlyCount *)(alt + offs - RC_CURLY_REGNODE_SIZE + 1));
4470              
4471 342           left.origin = a1->origin;
4472 342           left.rn = alt;
4473 342           left.spent = 0;
4474 342           rv = compare(1, &left, a2);
4475 342           free(alt);
4476 342           return rv;
4477             }
4478              
4479 300 100         if (anchored && !((cnt[0] == 1) && (cnt[1] == 1)))
    50          
    100          
4480             {
4481             /* fprintf(stderr, "anchored curly with variable length\n"); */
4482              
4483 7           alt = alloc_alt(p1 + RC_CURLY_REGNODE_SIZE, sz - RC_CURLY_REGNODE_SIZE);
4484 7 50         if (!alt)
4485             {
4486 0           return -1;
4487             }
4488              
4489 7           offs = get_jump_offset(p1);
4490 7 50         if (offs <= 0)
4491             {
4492 0           return -1;
4493             }
4494              
4495 7           q = p1 + offs;
4496 7 50         if (OP(q) != END)
4497             {
4498             /* repeat with a tail after it can be more strict than a
4499             fixed-length match only if the tail is at least as
4500             strict as the repeated regexp */
4501 0           left.origin = a1->origin;
4502 0           left.rn = q;
4503 0           left.spent = 0;
4504              
4505 0           end_offs = offs - 1;
4506 0           OP(alt + end_offs) = END;
4507              
4508 0           right.origin = a2->origin;
4509 0           right.rn = alt;
4510 0           right.spent = 0;
4511              
4512             /* fprintf(stderr, "comparing %d to %d\n", OP(left.rn),
4513             OP(right.rn)); */
4514 0           rv = compare(1, &left, &right);
4515 0           free(alt);
4516             /* fprintf(stderr, "compare returned %d\n", rv); */
4517 0 0         if (rv <= 0)
4518             {
4519 0           return rv;
4520             }
4521             }
4522             }
4523              
4524 300           left.origin = a1->origin;
4525 300           left.rn = p1 + RC_CURLY_REGNODE_SIZE;
4526 300           left.spent = 0;
4527 300           return compare(anchored, &left, a2);
4528             }
4529              
4530 476           static int compare_right_curly(int anchored, Arrow *a1, Arrow *a2)
4531             {
4532             regnode *p2, *alt;
4533             Arrow right;
4534             CurlyCount *cnt, *altcnt;
4535             int sz, rv, offs, nanch;
4536              
4537             /* fprintf(stderr, "enter compare_right_curly(%d...: a1->spent = %d, a2->spent = %d\n", anchored, a1->spent, a2->spent); */
4538              
4539 476           p2 = a2->rn;
4540              
4541 476           cnt = (CurlyCount *)(p2 + 1);
4542              
4543             /* fprintf(stderr, "compare_right_curly: minimal repeat count = %d\n", cnt[0]); */
4544              
4545 476           nanch = anchored;
4546              
4547 476 100         if (cnt[0] > 0)
4548             {
4549             /* the repeated expression is mandatory: */
4550 166           sz = get_size(p2);
4551 166 50         if (sz < 0)
4552             {
4553 0           return sz;
4554             }
4555              
4556 166 50         if (sz <= RC_CURLY_REGNODE_SIZE)
4557             {
4558 0           rc_error = "Right curly offset too small";
4559 0           return -1;
4560             }
4561              
4562 166           right.origin = a2->origin;
4563 166           right.rn = p2 + RC_CURLY_REGNODE_SIZE;
4564 166           right.spent = 0;
4565              
4566 166           rv = compare(anchored, a1, &right);
4567             /* fprintf(stderr, "compare_right_curly: compare returned %d\n", rv); */
4568 166 50         if (rv < 0)
4569             {
4570 0           return rv;
4571             }
4572              
4573 166 100         if (!rv)
4574             {
4575             /* ...or (if we aren't anchored yet) just do the left tail... */
4576 24           rv = compare_mismatch(anchored, a1, a2);
4577 24 50         if (rv)
4578             {
4579 0           return rv;
4580             }
4581              
4582             /* ...or (last try) unroll the repeat (works for e.g.
4583             'abbc' vs. 'ab{2}c' */
4584 24 100         if (cnt[0] > 1)
4585             {
4586 16 50         offs = GET_OFFSET(p2);
4587 16 50         if (offs < 0)
4588             {
4589 0           return -1;
4590             }
4591              
4592 16 50         if (offs < 3)
4593             {
4594 0           rc_error = "Left curly offset is too small";
4595 0           return -1;
4596             }
4597              
4598 16           alt = (regnode *)malloc(sizeof(regnode) * (offs - RC_CURLY_REGNODE_SIZE + sz));
4599 16 50         if (!alt)
4600             {
4601 0           rc_error = "Couldn't allocate memory for unrolled curly";
4602 0           return -1;
4603             }
4604              
4605 16           memcpy(alt, p2 + RC_CURLY_REGNODE_SIZE, (offs - RC_CURLY_REGNODE_SIZE) * sizeof(regnode));
4606 16           memcpy(alt + offs - RC_CURLY_REGNODE_SIZE, p2, sz * sizeof(regnode));
4607              
4608 16           dec_curly_counts((CurlyCount *)(alt + offs - RC_CURLY_REGNODE_SIZE + 1));
4609              
4610 16           right.origin = a2->origin;
4611 16           right.rn = alt;
4612 16           right.spent = 0;
4613              
4614 16           rv = compare(anchored, a1, &right);
4615 16           free(alt);
4616 16           return rv;
4617             }
4618              
4619 8           return 0;
4620             }
4621              
4622 142 100         if (cnt[0] == 1)
4623             {
4624 81           return 1;
4625             }
4626              
4627 61 100         if (OP(a1->rn) == END)
4628             {
4629             /* we presume the repeated argument matches something, which
4630             isn't guaranteed, but it is conservative */
4631 40           return 0;
4632             }
4633              
4634             /* strictly speaking, matching one repeat didn't *necessarily*
4635             anchor the match, but we'll ignore such cases as
4636             pathological */
4637 21           nanch = 1;
4638              
4639 21           alt = alloc_alt(p2, sz);
4640 21 50         if (!alt)
4641             {
4642 0           return -1;
4643             }
4644              
4645 21           altcnt = (CurlyCount *)(alt + 1);
4646 21           dec_curly_counts(altcnt);
4647 21 50         if (altcnt[1] > 0)
4648             {
4649 21           right.origin = a2->origin;
4650 21           right.rn = alt;
4651 21           right.spent = 0;
4652              
4653 21           rv = compare_right_curly(nanch, a1, &right);
4654             }
4655             else
4656             {
4657 0           rv = 1;
4658             }
4659              
4660 21           free(alt);
4661              
4662 21 100         if (rv <= 0)
4663             {
4664 2           return rv;
4665             }
4666              
4667 19           a2->rn += sz - 1;
4668             assert(OP(a2->rn) == END);
4669 19           a2->spent = 0;
4670 19           return rv;
4671             }
4672              
4673 310           return compare_right_curly_from_zero(nanch, a1, a2);
4674             }
4675              
4676 347           static int compare_curly_curly(int anchored, Arrow *a1, Arrow *a2)
4677             {
4678             regnode *p1, *p2, *e2;
4679             Arrow left, right;
4680             CurlyCount *cnt1, *cnt2;
4681             int rv, offs;
4682              
4683             /* fprintf(stderr, "enter compare_curly_curly(%d...)\n", anchored); */
4684              
4685 347           p1 = a1->rn;
4686             assert((OP(p1) == CURLY) || (OP(p1) == CURLYM) ||
4687             (OP(p1) == CURLYX));
4688 347           p2 = a2->rn;
4689             assert((OP(p2) == CURLY) || (OP(p2) == CURLYM) ||
4690             (OP(p2) == CURLYX));
4691              
4692 347           cnt1 = (CurlyCount *)(p1 + 1);
4693              
4694 347           cnt2 = (CurlyCount *)(p2 + 1);
4695              
4696 347 100         if (cnt2[0] > cnt1[0]) /* FIXME: fails '(?:aa){1,}' => 'a{2,}' */
4697             {
4698             /* fprintf(stderr, "curly mismatch\n"); */
4699 5           return compare_mismatch(anchored, a1, a2);
4700             }
4701              
4702 342           left.origin = a1->origin;
4703 342           left.rn = p1 + RC_CURLY_REGNODE_SIZE;
4704 342           left.spent = 0;
4705              
4706 342 100         if (cnt1[1] > cnt2[1])
4707             {
4708 36           offs = get_jump_offset(p2);
4709             /* fprintf(stderr, "offs = %d\n", offs); */
4710 36 50         if (offs <= 0)
4711             {
4712 0           return -1;
4713             }
4714              
4715 36           e2 = p2 + offs;
4716             /* fprintf(stderr, "e2->type = %d\n", e2->type); */
4717 36 100         if (OP(e2) != END)
4718             {
4719 3           return compare_mismatch(anchored, a1, a2);
4720             }
4721             }
4722              
4723 339           right.origin = a2->origin;
4724 339           right.rn = p2 + RC_CURLY_REGNODE_SIZE;
4725 339           right.spent = 0;
4726              
4727             /* fprintf(stderr, "comparing tails\n"); */
4728              
4729 339           rv = compare(anchored, &left, &right);
4730             /* fprintf(stderr, "tail compare returned %d\n", rv); */
4731 339 100         return (!rv && !cnt2[0]) ? compare_next(anchored, a1, a2) : rv;
    100          
4732             }
4733              
4734 120           static int compare_bound(int anchored, Arrow *a1, Arrow *a2,
4735             int move_left, unsigned char *bitmap, char *lookup,
4736             unsigned char *oktypes,
4737             unsigned char *regclasses, U32 regclasses_size)
4738             {
4739             Arrow left, right;
4740             unsigned char t;
4741             int i;
4742             char *seq;
4743              
4744             assert((OP(a2->rn) == BOUND) || (OP(a2->rn) == NBOUND));
4745              
4746 120           left = *a1;
4747              
4748 120 50         if (bump_with_check(&left) <= 0)
4749             {
4750 0           return -1;
4751             }
4752              
4753 120           t = OP(left.rn);
4754 120 50         if (t >= REGNODE_MAX)
4755             {
4756 0           rc_error = "Invalid node type";
4757 0           return -1;
4758             }
4759 120 50         else if (t == ANYOF)
4760             {
4761             /* fprintf(stderr, "next is bitmap; flags = 0x%x\n", left.rn->flags); */
4762              
4763 0 0         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
4764             {
4765 0 0         if (get_bitmap_byte(left.rn, i) & ~bitmap[i])
4766             {
4767 0           return compare_mismatch(anchored, a1, a2);
4768             }
4769             }
4770             }
4771 120 100         else if (t == ANYOFR)
4772             {
4773             unsigned char left_bitmap[ANYOF_BITMAP_SIZE];
4774              
4775 1 50         if (!convert_anyofr_to_bitmap(&left, left_bitmap))
4776             {
4777 0           return compare_mismatch(anchored, a1, a2);
4778             }
4779              
4780 33 100         for (i = 0; i < ANYOF_BITMAP_SIZE; ++i)
4781             {
4782 32 50         if (left_bitmap[i] & ~bitmap[i])
4783             {
4784 0           return compare_mismatch(anchored, a1, a2);
4785             }
4786             }
4787             }
4788 119 100         else if ((t == EXACT) || (t == EXACTF) || (t == EXACTFU))
    50          
    100          
4789             {
4790 87           seq = GET_LITERAL(&left);
4791 87 100         if (!lookup[(unsigned char)(*seq)])
4792             {
4793 43           return compare_mismatch(anchored, a1, a2);
4794             }
4795             }
4796 32 100         else if ((t == POSIXD) || (t == NPOSIXD) || (t == POSIXU) || (t == NPOSIXU))
    50          
    100          
    50          
4797 9           {
4798 9           U8 flags = FLAGS(left.rn);
4799 9 50         if ((flags >= regclasses_size) || !regclasses[flags])
    50          
4800             {
4801 0           return compare_mismatch(anchored, a1, a2);
4802             }
4803             }
4804 23 100         else if (!oktypes[t])
4805             {
4806 17           return compare_mismatch(anchored, a1, a2);
4807             }
4808              
4809 60           right = *a2;
4810 60 50         if (bump_with_check(&right) <= 0)
4811             {
4812 0           return -1;
4813             }
4814              
4815 111 100         return move_left ? compare(1, &left, &right) :
4816 51           compare(anchored, a1, &right);
4817             }
4818              
4819 8           static int compare_bol_word(int anchored, Arrow *a1, Arrow *a2)
4820             {
4821 8           return compare_bound(anchored, a1, a2, 1, word_bc.bitmap,
4822             word_bc.lookup, alphanumeric_classes,
4823             word_posix_regclasses, SIZEOF_ARRAY(word_posix_regclasses));
4824             }
4825              
4826 2           static int compare_bol_nword(int anchored, Arrow *a1, Arrow *a2)
4827             {
4828 2           return compare_bound(anchored, a1, a2, 1, word_bc.nbitmap,
4829             word_bc.nlookup, non_alphanumeric_classes,
4830             non_word_posix_regclasses, SIZEOF_ARRAY(non_word_posix_regclasses));
4831             }
4832              
4833 31           static int compare_next_word(int anchored, Arrow *a1, Arrow *a2)
4834             {
4835 31           return compare_bound(anchored, a1, a2, 0, word_bc.bitmap,
4836             word_bc.lookup, alphanumeric_classes,
4837             word_posix_regclasses, SIZEOF_ARRAY(word_posix_regclasses));
4838             }
4839              
4840 79           static int compare_next_nword(int anchored, Arrow *a1, Arrow *a2)
4841             {
4842 79           return compare_bound(anchored, a1, a2, 0, word_bc.nbitmap,
4843             word_bc.nlookup, non_alphanumeric_classes,
4844             non_word_posix_regclasses, SIZEOF_ARRAY(non_word_posix_regclasses));
4845             }
4846              
4847 7           static int compare_anyof_bounds(int anchored, Arrow *a1, Arrow *a2,
4848             unsigned char *bitmap1, unsigned char *bitmap2)
4849             {
4850             unsigned char loc;
4851             FCompare cmp[2];
4852             int i;
4853              
4854 7           cmp[0] = compare_next_word;
4855 7           cmp[1] = compare_next_nword;
4856 212 100         for (i = 0; (i < ANYOF_BITMAP_SIZE) && (cmp[0] || cmp[1]); ++i)
    100          
    100          
4857             {
4858 205 100         loc = bitmap1 ? bitmap1[i] : get_bitmap_byte(a1->rn, i);
4859              
4860 205 100         if (loc & ~bitmap2[i])
4861             {
4862 6           cmp[0] = 0;
4863             }
4864              
4865 205 100         if (loc & bitmap2[i])
4866             {
4867 4           cmp[1] = 0;
4868             }
4869             }
4870              
4871 7 100         if (cmp[0] && cmp[1])
    50          
4872             {
4873 0           rc_error = "Zero bitmap";
4874 0           return -1;
4875             }
4876              
4877 12 100         for (i = 0; i < SIZEOF_ARRAY(cmp); ++i)
4878             {
4879 11 100         if (cmp[i])
4880             {
4881 6           return (cmp[i])(anchored, a1, a2);
4882             }
4883             }
4884              
4885             /* if would be more elegant to use compare_mismatch as a sentinel
4886             in cmp, but VC 2003 then warns that this function might be
4887             missing a return... */
4888 1           return compare_mismatch(anchored, a1, a2);
4889             }
4890              
4891 2           static int compare_anyof_bound(int anchored, Arrow *a1, Arrow *a2)
4892             {
4893             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
4894             assert(OP(a2->rn) == BOUND);
4895              
4896 2           return compare_anyof_bounds(anchored, a1, a2, 0, word_bc.nbitmap);
4897             }
4898              
4899 0           static int compare_anyof_nbound(int anchored, Arrow *a1, Arrow *a2)
4900             {
4901             assert((OP(a1->rn) == ANYOF) || (OP(a1->rn) == ANYOFD));
4902             assert(OP(a2->rn) == NBOUND);
4903              
4904 0           return compare_anyof_bounds(anchored, a1, a2, 0, word_bc.bitmap);
4905             }
4906              
4907 1           static int compare_anyofr_bound(int anchored, Arrow *a1, Arrow *a2)
4908             {
4909             unsigned char left[ANYOF_BITMAP_SIZE];
4910              
4911             assert(OP(a1->rn) == ANYOFR);
4912             assert(OP(a2->rn) == BOUND);
4913              
4914 1 50         if (!convert_anyofr_to_bitmap(a1, left))
4915             {
4916 0           return compare_mismatch(anchored, a1, a2);
4917             }
4918              
4919 1           return compare_anyof_bounds(anchored, a1, a2, left, word_bc.nbitmap);
4920             }
4921              
4922 1           static int compare_anyofr_nbound(int anchored, Arrow *a1, Arrow *a2)
4923             {
4924             unsigned char left[ANYOF_BITMAP_SIZE];
4925              
4926             assert(OP(a1->rn) == ANYOFR);
4927             assert(OP(a2->rn) == NBOUND);
4928              
4929 1 50         if (!convert_anyofr_to_bitmap(a1, left))
4930             {
4931 0           return compare_mismatch(anchored, a1, a2);
4932             }
4933              
4934 1           return compare_anyof_bounds(anchored, a1, a2, left, word_bc.bitmap);
4935             }
4936              
4937 2           static int compare_anyofm_bound(int anchored, Arrow *a1, Arrow *a2)
4938             {
4939             unsigned char left[ANYOF_BITMAP_SIZE];
4940              
4941             assert(OP(a1->rn) == ANYOFM);
4942             assert(OP(a2->rn) == BOUND);
4943              
4944 2 50         if (!convert_anyofm_to_bitmap(a1, left))
4945             {
4946 0           return compare_mismatch(anchored, a1, a2);
4947             }
4948              
4949 2           return compare_anyof_bounds(anchored, a1, a2, left, word_bc.nbitmap);
4950             }
4951              
4952 1           static int compare_anyofm_nbound(int anchored, Arrow *a1, Arrow *a2)
4953             {
4954             unsigned char left[ANYOF_BITMAP_SIZE];
4955              
4956             assert(OP(a1->rn) == ANYOFM);
4957             assert(OP(a2->rn) == NBOUND);
4958              
4959 1 50         if (!convert_anyofm_to_bitmap(a1, left))
4960             {
4961 0           return compare_mismatch(anchored, a1, a2);
4962             }
4963              
4964 1           return compare_anyof_bounds(anchored, a1, a2, left, word_bc.bitmap);
4965             }
4966              
4967 63           static int compare_exact_bound(int anchored, Arrow *a1, Arrow *a2)
4968             {
4969             char *seq;
4970             FCompare cmp;
4971              
4972             assert((OP(a1->rn) == EXACT) || (OP(a1->rn) == EXACTF) ||
4973             (OP(a1->rn) == EXACTFU));
4974             assert(OP(a2->rn) == BOUND);
4975              
4976 63           seq = GET_LITERAL(a1);
4977              
4978 126           cmp = word_bc.lookup[(unsigned char)(*seq)] ?
4979 63 100         compare_next_nword : compare_next_word;
4980 63           return cmp(anchored, a1, a2);
4981             }
4982              
4983 17           static int compare_exact_nbound(int anchored, Arrow *a1, Arrow *a2)
4984             {
4985             char *seq;
4986             FCompare cmp;
4987              
4988             assert((OP(a1->rn) == EXACT) || (OP(a1->rn) == EXACTF) ||
4989             (OP(a1->rn) == EXACTFU));
4990             assert(OP(a2->rn) == NBOUND);
4991              
4992 17           seq = GET_LITERAL(a1);
4993              
4994 34           cmp = word_bc.lookup[(unsigned char)(*seq)] ?
4995 17 100         compare_next_word : compare_next_nword;
4996 17           return cmp(anchored, a1, a2);
4997             }
4998              
4999 11           static int compare_posix_bound(int anchored, Arrow *a1, Arrow *a2)
5000             {
5001             assert((OP(a1->rn) == POSIXD) || (OP(a1->rn) == POSIXU) ||
5002             (OP(a1->rn) == POSIXA));
5003             assert(OP(a2->rn) == BOUND);
5004              
5005 11           U8 flags = FLAGS(a1->rn);
5006 11 50         if ((flags >= SIZEOF_ARRAY(word_posix_regclasses)) ||
    50          
5007 11           (flags >= SIZEOF_ARRAY(non_word_posix_regclasses)) ||
5008 11 100         (!word_posix_regclasses[flags] && !non_word_posix_regclasses[flags]))
    50          
5009             {
5010 0           return compare_mismatch(anchored, a1, a2);
5011             }
5012              
5013             assert(!word_posix_regclasses[flags] || !non_word_posix_regclasses[flags]);
5014              
5015 22           FCompare cmp = word_posix_regclasses[flags] ?
5016 11 100         compare_next_nword : compare_next_word;
5017 11           return cmp(anchored, a1, a2);
5018             }
5019              
5020 9           static int compare_posix_nbound(int anchored, Arrow *a1, Arrow *a2)
5021             {
5022             assert((OP(a1->rn) == POSIXD) || (OP(a1->rn) == POSIXU) ||
5023             (OP(a1->rn) == POSIXA));
5024             assert(OP(a2->rn) == NBOUND);
5025              
5026 9           U8 flags = FLAGS(a1->rn);
5027 9 50         if ((flags >= SIZEOF_ARRAY(word_posix_regclasses)) ||
    50          
5028 9           (flags >= SIZEOF_ARRAY(non_word_posix_regclasses)) ||
5029 9 100         (!word_posix_regclasses[flags] && !non_word_posix_regclasses[flags]))
    50          
5030             {
5031 0           return compare_mismatch(anchored, a1, a2);
5032             }
5033              
5034             assert(!word_posix_regclasses[flags] || !non_word_posix_regclasses[flags]);
5035              
5036 18           FCompare cmp = word_posix_regclasses[flags] ?
5037 9 100         compare_next_word : compare_next_nword;
5038 9           return cmp(anchored, a1, a2);
5039             }
5040              
5041 5           static int compare_negative_posix_word_bound(int anchored, Arrow *a1, Arrow *a2)
5042             {
5043             assert((OP(a1->rn) == NPOSIXD) || (OP(a1->rn) == NPOSIXU) ||
5044             (OP(a1->rn) == NPOSIXA));
5045             assert(OP(a2->rn) == BOUND);
5046              
5047             /* we could accept _CC_ALPHANUMERIC as well but let's postpone it
5048             until we see the need */
5049 5 100         if (FLAGS(a1->rn) != CC_WORDCHAR_)
5050             {
5051 3           return compare_mismatch(anchored, a1, a2);
5052             }
5053              
5054 2           return compare_next_word(anchored, a1, a2);
5055             }
5056              
5057 9           static int compare_negative_posix_word_nbound(int anchored, Arrow *a1, Arrow *a2)
5058             {
5059             assert((OP(a1->rn) == NPOSIXD) || (OP(a1->rn) == NPOSIXU) ||
5060             (OP(a1->rn) == NPOSIXA));
5061             assert(OP(a2->rn) == NBOUND);
5062              
5063             /* we could accept _CC_ALPHANUMERIC as well but let's postpone it
5064             until we see the need */
5065 9 100         if (FLAGS(a1->rn) != CC_WORDCHAR_)
5066             {
5067 7           return compare_mismatch(anchored, a1, a2);
5068             }
5069              
5070 2           return compare_next_nword(anchored, a1, a2);
5071             }
5072              
5073 50           static int compare_open_open(int anchored, Arrow *a1, Arrow *a2)
5074             {
5075 50           return compare_tails(anchored, a1, a2);
5076             }
5077              
5078 220           static int compare_left_open(int anchored, Arrow *a1, Arrow *a2)
5079             {
5080 220           return compare_left_tail(anchored, a1, a2);
5081             }
5082              
5083 209           static int compare_right_open(int anchored, Arrow *a1, Arrow *a2)
5084             {
5085 209           return compare_next(anchored, a1, a2);
5086             }
5087              
5088 10037           static int success(int anchored, Arrow *a1, Arrow *a2)
5089             {
5090 10037           return 1;
5091             }
5092              
5093             /* #define DEBUG_dump */
5094              
5095 9168           int rc_compare(REGEXP *pt1, REGEXP *pt2)
5096             {
5097             Arrow a1, a2;
5098             regnode *p1, *p2;
5099             #ifdef DEBUG_dump
5100             unsigned char *p;
5101             int i;
5102             #endif
5103              
5104 9168           a1.origin = SvANY(pt1);
5105 9168           a2.origin = SvANY(pt2);
5106              
5107 9168 100         if ((get_forced_semantics(pt1) | get_forced_semantics(pt2)) == FORCED_MISMATCH)
5108             {
5109 7           return 0;
5110             }
5111              
5112 9161           p1 = find_internal(a1.origin);
5113 9161 50         if (!p1)
5114             {
5115 0           return -1;
5116             }
5117              
5118 9161           p2 = find_internal(a2.origin);
5119 9161 50         if (!p2)
5120             {
5121 0           return -1;
5122             }
5123              
5124             #ifdef DEBUG_dump
5125             p = (unsigned char *)p1;
5126             for (i = 1; i <= 64; ++i)
5127             {
5128             fprintf(stderr, " %02x", (int)p[i - 1]);
5129             if (!(i % 4))
5130             {
5131             fprintf(stderr, "\n");
5132             }
5133             }
5134              
5135             fprintf(stderr, "\n\n");
5136              
5137             p = (unsigned char *)p2;
5138             for (i = 1; i <= 64; ++i)
5139             {
5140             fprintf(stderr, " %02x", (int)p[i - 1]);
5141             if (!(i % 4))
5142             {
5143             fprintf(stderr, "\n");
5144             }
5145             }
5146              
5147             fprintf(stderr, "\n\n");
5148             #endif
5149              
5150 9161           a1.rn = p1;
5151 9161           a1.spent = 0;
5152 9161           a2.rn = p2;
5153 9161           a2.spent = 0;
5154              
5155 9161           return compare(0, &a1, &a2);
5156             }
5157              
5158 38001           static int compare(int anchored, Arrow *a1, Arrow *a2)
5159             {
5160             FCompare cmp;
5161              
5162             /* fprintf(stderr, "enter compare(%d, %d, %d)\n", anchored,
5163             OP(a1->rn), OP(a2->rn)); */
5164              
5165 38001 50         if ((OP(a1->rn) >= REGNODE_MAX) || (OP(a2->rn) >= REGNODE_MAX))
    50          
5166             {
5167 0           rc_error = "Invalid regexp node type";
5168 0           return -1;
5169             }
5170              
5171 38001           cmp = dispatch[OP(a1->rn)][OP(a2->rn)];
5172 38001 100         if (!cmp)
5173             {
5174             /* fprintf(stderr, "no comparator\n"); */
5175 963           return 0;
5176             }
5177              
5178 37038           return cmp(anchored, a1, a2);
5179             }
5180              
5181 1           void rc_init()
5182             {
5183             int i, wstart;
5184              
5185             /* could have used compile-time assertion, but why bother
5186             making it compatible... */
5187             assert(ANYOF_BITMAP_SIZE == 32);
5188              
5189 1           init_forced_byte();
5190              
5191 1           init_byte_class(&whitespace, whitespace_expl,
5192             SIZEOF_ARRAY(whitespace_expl));
5193 1           init_byte_class(&horizontal_whitespace, horizontal_whitespace_expl,
5194             SIZEOF_ARRAY(horizontal_whitespace_expl));
5195 1           init_byte_class(&vertical_whitespace, vertical_whitespace_expl,
5196             SIZEOF_ARRAY(vertical_whitespace_expl));
5197              
5198 11 100         for (i = 0; i < SIZEOF_ARRAY(digit_expl); ++i)
5199             {
5200 10           digit_expl[i] = '0' + i;
5201             }
5202              
5203 1           init_byte_class(&digit, digit_expl, SIZEOF_ARRAY(digit_expl));
5204              
5205 1           memcpy(xdigit_expl, digit_expl, 10 * sizeof(char));
5206              
5207 1           wstart = 10;
5208 7 100         for (i = 0; i < 6; ++i)
5209             {
5210 6           xdigit_expl[wstart + i] = 'a' + i;
5211             }
5212              
5213 1           wstart += 6;
5214 7 100         for (i = 0; i < 6; ++i)
5215             {
5216 6           xdigit_expl[wstart + i] = 'A' + i;
5217             }
5218              
5219 1           init_byte_class(&xdigit, xdigit_expl, SIZEOF_ARRAY(xdigit_expl));
5220              
5221 1           init_byte_class(&ndot, ndot_expl, SIZEOF_ARRAY(ndot_expl));
5222              
5223 1           alphanumeric_expl[0] = '_';
5224              
5225 1           wstart = 1;
5226 1           memcpy(alphanumeric_expl + wstart, digit_expl, 10 * sizeof(char));
5227              
5228 1           wstart += 10;
5229 27 100         for (i = 0; i < LETTER_COUNT; ++i)
5230             {
5231 26           alphanumeric_expl[wstart + i] = 'a' + i;
5232             }
5233              
5234 1           wstart += LETTER_COUNT;
5235 27 100         for (i = 0; i < LETTER_COUNT; ++i)
5236             {
5237 26           alphanumeric_expl[wstart + i] = 'A' + i;
5238             }
5239              
5240 1           init_byte_class(&word_bc, alphanumeric_expl,
5241             SIZEOF_ARRAY(alphanumeric_expl));
5242 1           init_byte_class(&alnum_bc, alphanumeric_expl + 1,
5243             SIZEOF_ARRAY(alphanumeric_expl) - 1);
5244              
5245 27 100         for (i = 0; i < LETTER_COUNT; ++i)
5246             {
5247 26           alpha_expl[i] = lower_expl[i] = 'a' + i;
5248             }
5249              
5250 1           wstart = LETTER_COUNT;
5251 27 100         for (i = 0; i < LETTER_COUNT; ++i)
5252             {
5253 26           alpha_expl[wstart + i] = upper_expl[i] = 'A' + i;
5254             }
5255              
5256 1           init_byte_class(&alpha_bc, alpha_expl,
5257             SIZEOF_ARRAY(alpha_expl));
5258 1           init_byte_class(&lower_bc, lower_expl,
5259             SIZEOF_ARRAY(lower_expl));
5260 1           init_byte_class(&upper_bc, upper_expl,
5261             SIZEOF_ARRAY(upper_expl));
5262              
5263 1           memset(alphanumeric_classes, 0, SIZEOF_ARRAY(alphanumeric_classes));
5264              
5265 1           memset(non_alphanumeric_classes, 0,
5266             SIZEOF_ARRAY(non_alphanumeric_classes));
5267 1           non_alphanumeric_classes[EOS] = non_alphanumeric_classes[EOL] =
5268 1           non_alphanumeric_classes[SEOL] = 1;
5269              
5270 1           memset(word_posix_regclasses, 0,
5271             SIZEOF_ARRAY(word_posix_regclasses));
5272 1           word_posix_regclasses[CC_WORDCHAR_] =
5273 1           word_posix_regclasses[CC_DIGIT_] =
5274 1           word_posix_regclasses[CC_ALPHA_] =
5275 1           word_posix_regclasses[CC_LOWER_] =
5276 1           word_posix_regclasses[CC_UPPER_] =
5277 1           word_posix_regclasses[CC_UPPER_] =
5278 1           word_posix_regclasses[CC_ALPHANUMERIC_] =
5279 1           word_posix_regclasses[CC_CASED_] =
5280 1           word_posix_regclasses[CC_XDIGIT_] = 1;
5281              
5282 1           memset(non_word_posix_regclasses, 0,
5283             SIZEOF_ARRAY(non_word_posix_regclasses));
5284 1           non_word_posix_regclasses[CC_PUNCT_] =
5285 1           non_word_posix_regclasses[CC_SPACE_] =
5286 1           non_word_posix_regclasses[CC_BLANK_] =
5287 1           non_word_posix_regclasses[CC_VERTSPACE_] = 1;
5288              
5289 1           memset(newline_posix_regclasses, 0,
5290             SIZEOF_ARRAY(newline_posix_regclasses));
5291 1           newline_posix_regclasses[CC_SPACE_] =
5292 1           newline_posix_regclasses[CC_CNTRL_] =
5293 1           newline_posix_regclasses[CC_ASCII_] =
5294 1           newline_posix_regclasses[CC_VERTSPACE_] = 1;
5295              
5296 1           memset(trivial_nodes, 0, SIZEOF_ARRAY(trivial_nodes));
5297 1           trivial_nodes[SUCCEED] = trivial_nodes[NOTHING] =
5298 1           trivial_nodes[TAIL] = trivial_nodes[WHILEM] =
5299 1           trivial_nodes[LOOKBEHIND_END] = 1;
5300              
5301 1           memset(dispatch, 0, sizeof(FCompare) * REGNODE_MAX * REGNODE_MAX);
5302              
5303 112 100         for (i = 0; i < REGNODE_MAX; ++i)
5304             {
5305 111           dispatch[i][END] = success;
5306             }
5307              
5308 112 100         for (i = 0; i < REGNODE_MAX; ++i)
5309             {
5310 111           dispatch[i][SUCCEED] = compare_next;
5311             }
5312              
5313 1           dispatch[SUCCEED][SUCCEED] = compare_tails;
5314              
5315 1           dispatch[SUCCEED][MBOL] = compare_left_tail;
5316 1           dispatch[MBOL][MBOL] = compare_tails;
5317 1           dispatch[SBOL][MBOL] = compare_tails;
5318 1           dispatch[REG_ANY][MBOL] = compare_mismatch;
5319 1           dispatch[SANY][MBOL] = compare_mismatch;
5320 1           dispatch[ANYOF][MBOL] = compare_anyof_multiline;
5321 1           dispatch[ANYOFD][MBOL] = compare_anyof_multiline;
5322 1           dispatch[ANYOFR][MBOL] = compare_anyofr_multiline;
5323 1           dispatch[ANYOFM][MBOL] = compare_anyofm_multiline;
5324 1           dispatch[NANYOFM][MBOL] = compare_nanyofm_multiline;
5325 1           dispatch[POSIXD][MBOL] = compare_mismatch;
5326 1           dispatch[POSIXU][MBOL] = compare_mismatch;
5327 1           dispatch[POSIXA][MBOL] = compare_mismatch;
5328 1           dispatch[NPOSIXD][MBOL] = compare_mismatch;
5329 1           dispatch[NPOSIXU][MBOL] = compare_mismatch;
5330 1           dispatch[NPOSIXA][MBOL] = compare_mismatch;
5331 1           dispatch[BRANCH][MBOL] = compare_left_branch;
5332 1           dispatch[EXACT][MBOL] = compare_exact_multiline;
5333 1           dispatch[EXACTF][MBOL] = compare_exact_multiline;
5334 1           dispatch[EXACTFU][MBOL] = compare_exact_multiline;
5335 1           dispatch[NOTHING][MBOL] = compare_left_tail;
5336 1           dispatch[TAIL][MBOL] = compare_left_tail;
5337 1           dispatch[STAR][MBOL] = compare_mismatch;
5338 1           dispatch[PLUS][MBOL] = compare_left_plus;
5339 1           dispatch[CURLY][MBOL] = compare_left_curly;
5340 1           dispatch[CURLYM][MBOL] = compare_left_curly;
5341 1           dispatch[CURLYX][MBOL] = compare_left_curly;
5342 1           dispatch[WHILEM][MBOL] = compare_left_tail;
5343 1           dispatch[OPEN][MBOL] = compare_left_open;
5344 1           dispatch[CLOSE][MBOL] = compare_left_tail;
5345 1           dispatch[IFMATCH][MBOL] = compare_after_assertion;
5346 1           dispatch[UNLESSM][MBOL] = compare_after_assertion;
5347 1           dispatch[OPFAIL][MBOL] = compare_after_alt_assertion;
5348 1           dispatch[MINMOD][MBOL] = compare_left_tail;
5349 1           dispatch[LNBREAK][MBOL] = compare_tails;
5350 1           dispatch[LOOKBEHIND_END][MBOL] = compare_left_tail;
5351 1           dispatch[OPTIMIZED][MBOL] = compare_left_tail;
5352              
5353 1           dispatch[SUCCEED][SBOL] = compare_left_tail;
5354 1           dispatch[SBOL][SBOL] = compare_tails;
5355 1           dispatch[BRANCH][SBOL] = compare_left_branch;
5356 1           dispatch[NOTHING][SBOL] = compare_left_tail;
5357 1           dispatch[TAIL][SBOL] = compare_left_tail;
5358 1           dispatch[STAR][SBOL] = compare_mismatch;
5359 1           dispatch[PLUS][SBOL] = compare_left_plus;
5360 1           dispatch[CURLY][SBOL] = compare_left_curly;
5361 1           dispatch[CURLYM][SBOL] = compare_left_curly;
5362 1           dispatch[CURLYX][SBOL] = compare_left_curly;
5363 1           dispatch[WHILEM][SBOL] = compare_left_tail;
5364 1           dispatch[OPEN][SBOL] = compare_left_open;
5365 1           dispatch[CLOSE][SBOL] = compare_left_tail;
5366 1           dispatch[IFMATCH][SBOL] = compare_after_assertion;
5367 1           dispatch[UNLESSM][SBOL] = compare_after_assertion;
5368 1           dispatch[OPFAIL][SBOL] = compare_after_alt_assertion;
5369 1           dispatch[MINMOD][SBOL] = compare_left_tail;
5370 1           dispatch[LOOKBEHIND_END][SBOL] = compare_left_tail;
5371 1           dispatch[OPTIMIZED][SBOL] = compare_left_tail;
5372              
5373 1           dispatch[SUCCEED][EOS] = compare_left_tail;
5374 1           dispatch[EOS][EOS] = compare_tails;
5375 1           dispatch[EOL][EOS] = compare_mismatch;
5376 1           dispatch[SEOL][EOS] = compare_mismatch;
5377 1           dispatch[BRANCH][EOS] = compare_left_branch;
5378 1           dispatch[NOTHING][EOS] = compare_left_tail;
5379 1           dispatch[TAIL][EOS] = compare_left_tail;
5380 1           dispatch[STAR][EOS] = compare_mismatch;
5381 1           dispatch[PLUS][EOS] = compare_left_plus;
5382 1           dispatch[CURLY][EOS] = compare_left_curly;
5383 1           dispatch[CURLYM][EOS] = compare_left_curly;
5384 1           dispatch[CURLYX][EOS] = compare_left_curly;
5385 1           dispatch[WHILEM][EOS] = compare_left_tail;
5386 1           dispatch[OPEN][EOS] = compare_left_open;
5387 1           dispatch[CLOSE][EOS] = compare_left_tail;
5388 1           dispatch[IFMATCH][EOS] = compare_after_assertion;
5389 1           dispatch[UNLESSM][EOS] = compare_after_assertion;
5390 1           dispatch[OPFAIL][EOS] = compare_after_alt_assertion;
5391 1           dispatch[MINMOD][EOS] = compare_left_tail;
5392 1           dispatch[LOOKBEHIND_END][EOS] = compare_left_tail;
5393 1           dispatch[OPTIMIZED][EOS] = compare_left_tail;
5394              
5395 1           dispatch[SUCCEED][EOL] = compare_left_tail;
5396 1           dispatch[EOS][EOL] = compare_tails;
5397 1           dispatch[EOL][EOL] = compare_tails;
5398 1           dispatch[SEOL][EOL] = compare_tails;
5399 1           dispatch[BRANCH][EOL] = compare_left_branch;
5400 1           dispatch[NOTHING][EOL] = compare_left_tail;
5401 1           dispatch[TAIL][EOL] = compare_left_tail;
5402 1           dispatch[STAR][EOL] = compare_mismatch;
5403 1           dispatch[PLUS][EOL] = compare_left_plus;
5404 1           dispatch[CURLY][EOL] = compare_left_curly;
5405 1           dispatch[CURLYM][EOL] = compare_left_curly;
5406 1           dispatch[CURLYX][EOL] = compare_left_curly;
5407 1           dispatch[WHILEM][EOL] = compare_left_tail;
5408 1           dispatch[OPEN][EOL] = compare_left_open;
5409 1           dispatch[CLOSE][EOL] = compare_left_tail;
5410 1           dispatch[IFMATCH][EOL] = compare_after_assertion;
5411 1           dispatch[UNLESSM][EOL] = compare_after_assertion;
5412 1           dispatch[OPFAIL][EOL] = compare_after_alt_assertion;
5413 1           dispatch[MINMOD][EOL] = compare_left_tail;
5414 1           dispatch[LOOKBEHIND_END][EOL] = compare_left_tail;
5415 1           dispatch[OPTIMIZED][EOL] = compare_left_tail;
5416              
5417 1           dispatch[SUCCEED][MEOL] = compare_left_tail;
5418 1           dispatch[EOS][MEOL] = compare_tails;
5419 1           dispatch[EOL][MEOL] = compare_tails;
5420 1           dispatch[MEOL][MEOL] = compare_tails;
5421 1           dispatch[SEOL][MEOL] = compare_tails;
5422 1           dispatch[REG_ANY][MEOL] = compare_mismatch;
5423 1           dispatch[SANY][MEOL] = compare_mismatch;
5424 1           dispatch[ANYOF][MEOL] = compare_anyof_multiline; /* not in tests; remove? */
5425 1           dispatch[POSIXD][MEOL] = compare_mismatch;
5426 1           dispatch[POSIXU][MEOL] = compare_mismatch;
5427 1           dispatch[POSIXA][MEOL] = compare_mismatch;
5428 1           dispatch[NPOSIXD][MEOL] = compare_mismatch;
5429 1           dispatch[NPOSIXU][MEOL] = compare_mismatch;
5430 1           dispatch[NPOSIXA][MEOL] = compare_mismatch;
5431 1           dispatch[BRANCH][MEOL] = compare_left_branch;
5432 1           dispatch[EXACT][MEOL] = compare_exact_multiline;
5433 1           dispatch[EXACTF][MEOL] = compare_exact_multiline;
5434 1           dispatch[EXACTFU][MEOL] = compare_exact_multiline;
5435 1           dispatch[NOTHING][MEOL] = compare_left_tail;
5436 1           dispatch[TAIL][MEOL] = compare_left_tail;
5437 1           dispatch[STAR][MEOL] = compare_mismatch;
5438 1           dispatch[PLUS][MEOL] = compare_left_plus;
5439 1           dispatch[CURLY][MEOL] = compare_left_curly;
5440 1           dispatch[CURLYM][MEOL] = compare_left_curly;
5441 1           dispatch[CURLYX][MEOL] = compare_left_curly;
5442 1           dispatch[WHILEM][MEOL] = compare_left_tail;
5443 1           dispatch[OPEN][MEOL] = compare_left_open;
5444 1           dispatch[CLOSE][MEOL] = compare_left_tail;
5445 1           dispatch[IFMATCH][MEOL] = compare_after_assertion;
5446 1           dispatch[UNLESSM][MEOL] = compare_after_assertion;
5447 1           dispatch[OPFAIL][MEOL] = compare_after_alt_assertion;
5448 1           dispatch[MINMOD][MEOL] = compare_left_tail;
5449 1           dispatch[LNBREAK][MEOL] = compare_mismatch;
5450 1           dispatch[LOOKBEHIND_END][MEOL] = compare_left_tail;
5451 1           dispatch[OPTIMIZED][MEOL] = compare_left_tail;
5452              
5453 1           dispatch[SUCCEED][SEOL] = compare_left_tail;
5454 1           dispatch[EOS][SEOL] = compare_tails;
5455 1           dispatch[EOL][SEOL] = compare_tails;
5456 1           dispatch[SEOL][SEOL] = compare_tails;
5457 1           dispatch[BRANCH][SEOL] = compare_left_branch;
5458 1           dispatch[NOTHING][SEOL] = compare_left_tail;
5459 1           dispatch[POSIXD][SEOL] = compare_mismatch;
5460 1           dispatch[POSIXU][SEOL] = compare_mismatch;
5461 1           dispatch[POSIXA][SEOL] = compare_mismatch;
5462 1           dispatch[NPOSIXD][SEOL] = compare_mismatch;
5463 1           dispatch[NPOSIXU][SEOL] = compare_mismatch;
5464 1           dispatch[NPOSIXA][SEOL] = compare_mismatch;
5465 1           dispatch[TAIL][SEOL] = compare_left_tail;
5466 1           dispatch[STAR][SEOL] = 0;
5467 1           dispatch[PLUS][SEOL] = compare_left_plus;
5468 1           dispatch[CURLY][SEOL] = compare_left_curly;
5469 1           dispatch[CURLYM][SEOL] = compare_left_curly;
5470 1           dispatch[CURLYX][SEOL] = compare_left_curly;
5471 1           dispatch[WHILEM][SEOL] = compare_left_tail;
5472 1           dispatch[OPEN][SEOL] = compare_left_open;
5473 1           dispatch[CLOSE][SEOL] = compare_left_tail;
5474 1           dispatch[IFMATCH][SEOL] = compare_after_assertion;
5475 1           dispatch[UNLESSM][SEOL] = compare_after_assertion;
5476 1           dispatch[OPFAIL][SEOL] = compare_after_alt_assertion;
5477 1           dispatch[MINMOD][SEOL] = compare_left_tail;
5478 1           dispatch[LNBREAK][SEOL] = compare_mismatch;
5479 1           dispatch[LOOKBEHIND_END][SEOL] = compare_left_tail;
5480 1           dispatch[OPTIMIZED][SEOL] = compare_left_tail;
5481              
5482 1           dispatch[SUCCEED][BOUND] = compare_left_tail;
5483 1           dispatch[MBOL][BOUND] = compare_bol_word;
5484 1           dispatch[SBOL][BOUND] = compare_bol_word;
5485 1           dispatch[BOUND][BOUND] = compare_tails;
5486 1           dispatch[NBOUND][BOUND] = compare_mismatch;
5487 1           dispatch[REG_ANY][BOUND] = compare_mismatch;
5488 1           dispatch[SANY][BOUND] = compare_mismatch;
5489 1           dispatch[ANYOF][BOUND] = compare_anyof_bound;
5490 1           dispatch[ANYOFD][BOUND] = compare_anyof_bound;
5491 1           dispatch[ANYOFR][BOUND] = compare_anyofr_bound;
5492 1           dispatch[ANYOFM][BOUND] = compare_anyofm_bound;
5493 1           dispatch[NANYOFM][BOUND] = compare_mismatch;
5494 1           dispatch[POSIXD][BOUND] = compare_posix_bound;
5495 1           dispatch[POSIXU][BOUND] = compare_posix_bound;
5496 1           dispatch[POSIXA][BOUND] = compare_posix_bound;
5497 1           dispatch[NPOSIXD][BOUND] = compare_negative_posix_word_bound;
5498 1           dispatch[NPOSIXU][BOUND] = compare_mismatch; /* should be replaced, needs extra test */
5499 1           dispatch[NPOSIXA][BOUND] = compare_negative_posix_word_bound;
5500 1           dispatch[BRANCH][BOUND] = compare_left_branch;
5501 1           dispatch[EXACT][BOUND] = compare_exact_bound;
5502 1           dispatch[EXACTF][BOUND] = compare_exact_bound;
5503 1           dispatch[EXACTFU][BOUND] = compare_exact_bound;
5504 1           dispatch[NOTHING][BOUND] = compare_left_tail;
5505 1           dispatch[TAIL][BOUND] = compare_left_tail;
5506 1           dispatch[CURLY][BOUND] = compare_left_curly;
5507 1           dispatch[CURLYM][BOUND] = compare_left_curly;
5508 1           dispatch[CURLYX][BOUND] = compare_left_curly;
5509 1           dispatch[WHILEM][BOUND] = compare_left_tail;
5510 1           dispatch[OPEN][BOUND] = compare_left_open;
5511 1           dispatch[CLOSE][BOUND] = compare_left_tail;
5512 1           dispatch[IFMATCH][BOUND] = compare_after_assertion;
5513 1           dispatch[UNLESSM][BOUND] = compare_after_assertion;
5514 1           dispatch[OPFAIL][BOUND] = compare_after_alt_assertion;
5515 1           dispatch[MINMOD][BOUND] = compare_left_tail;
5516 1           dispatch[LNBREAK][BOUND] = compare_mismatch;
5517 1           dispatch[LOOKBEHIND_END][BOUND] = compare_left_tail;
5518 1           dispatch[OPTIMIZED][BOUND] = compare_left_tail;
5519              
5520 1           dispatch[SUCCEED][NBOUND] = compare_left_tail;
5521 1           dispatch[MBOL][NBOUND] = compare_bol_nword;
5522 1           dispatch[SBOL][NBOUND] = compare_bol_nword;
5523 1           dispatch[BOUND][NBOUND] = compare_mismatch;
5524 1           dispatch[NBOUND][NBOUND] = compare_tails;
5525 1           dispatch[REG_ANY][NBOUND] = compare_mismatch;
5526 1           dispatch[SANY][NBOUND] = compare_mismatch;
5527 1           dispatch[ANYOF][NBOUND] = compare_anyof_nbound;
5528 1           dispatch[ANYOFD][NBOUND] = compare_anyof_nbound;
5529 1           dispatch[ANYOFR][NBOUND] = compare_anyofr_nbound;
5530 1           dispatch[ANYOFM][NBOUND] = compare_anyofm_nbound;
5531 1           dispatch[NANYOFM][NBOUND] = compare_mismatch;
5532 1           dispatch[POSIXD][NBOUND] = compare_posix_nbound;
5533 1           dispatch[POSIXU][NBOUND] = compare_posix_nbound;
5534 1           dispatch[POSIXA][NBOUND] = compare_posix_nbound;
5535 1           dispatch[NPOSIXD][NBOUND] = compare_negative_posix_word_nbound;
5536 1           dispatch[NPOSIXU][NBOUND] = compare_negative_posix_word_nbound;
5537 1           dispatch[NPOSIXA][NBOUND] = compare_negative_posix_word_nbound;
5538 1           dispatch[BRANCH][NBOUND] = compare_left_branch;
5539 1           dispatch[EXACT][NBOUND] = compare_exact_nbound;
5540 1           dispatch[EXACTF][NBOUND] = compare_exact_nbound;
5541 1           dispatch[EXACTFU][NBOUND] = compare_exact_nbound;
5542 1           dispatch[NOTHING][NBOUND] = compare_left_tail;
5543 1           dispatch[TAIL][NBOUND] = compare_left_tail;
5544 1           dispatch[CURLY][NBOUND] = compare_left_curly;
5545 1           dispatch[CURLYM][NBOUND] = compare_left_curly;
5546 1           dispatch[CURLYX][NBOUND] = compare_left_curly;
5547 1           dispatch[WHILEM][NBOUND] = compare_left_tail;
5548 1           dispatch[OPEN][NBOUND] = compare_left_open;
5549 1           dispatch[CLOSE][NBOUND] = compare_left_tail;
5550 1           dispatch[IFMATCH][NBOUND] = compare_after_assertion;
5551 1           dispatch[UNLESSM][NBOUND] = compare_after_assertion;
5552 1           dispatch[OPFAIL][NBOUND] = compare_after_alt_assertion;
5553 1           dispatch[MINMOD][NBOUND] = compare_left_tail;
5554 1           dispatch[LNBREAK][NBOUND] = compare_mismatch;
5555 1           dispatch[LOOKBEHIND_END][NBOUND] = compare_left_tail;
5556 1           dispatch[OPTIMIZED][NBOUND] = compare_left_tail;
5557              
5558 1           dispatch[SUCCEED][REG_ANY] = compare_left_tail;
5559 1           dispatch[MBOL][REG_ANY] = compare_bol;
5560 1           dispatch[SBOL][REG_ANY] = compare_bol;
5561 1           dispatch[BOUND][REG_ANY] = compare_mismatch;
5562 1           dispatch[NBOUND][REG_ANY] = compare_mismatch;
5563 1           dispatch[REG_ANY][REG_ANY] = compare_tails;
5564 1           dispatch[SANY][REG_ANY] = compare_mismatch;
5565 1           dispatch[ANYOF][REG_ANY] = compare_anyof_reg_any;
5566 1           dispatch[ANYOFD][REG_ANY] = compare_anyof_reg_any;
5567 1           dispatch[ANYOFR][REG_ANY] = compare_anyofr_reg_any;
5568 1           dispatch[ANYOFM][REG_ANY] = compare_anyofm_reg_any;
5569 1           dispatch[NANYOFM][REG_ANY] = compare_nanyofm_reg_any;
5570 1           dispatch[POSIXD][REG_ANY] = compare_posix_reg_any;
5571 1           dispatch[POSIXU][REG_ANY] = compare_posix_reg_any;
5572 1           dispatch[POSIXA][REG_ANY] = compare_posix_reg_any;
5573 1           dispatch[NPOSIXD][REG_ANY] = compare_negative_posix_reg_any;
5574 1           dispatch[NPOSIXU][REG_ANY] = compare_negative_posix_reg_any;
5575 1           dispatch[NPOSIXA][REG_ANY] = compare_negative_posix_reg_any;
5576 1           dispatch[BRANCH][REG_ANY] = compare_left_branch;
5577 1           dispatch[EXACT][REG_ANY] = compare_exact_reg_any;
5578 1           dispatch[EXACTF][REG_ANY] = compare_exact_reg_any;
5579 1           dispatch[EXACTFU][REG_ANY] = compare_exact_reg_any;
5580 1           dispatch[NOTHING][REG_ANY] = compare_left_tail;
5581 1           dispatch[TAIL][REG_ANY] = compare_left_tail;
5582 1           dispatch[STAR][REG_ANY] = compare_mismatch;
5583 1           dispatch[PLUS][REG_ANY] = compare_left_plus;
5584 1           dispatch[CURLY][REG_ANY] = compare_left_curly;
5585 1           dispatch[CURLYM][REG_ANY] = compare_left_curly;
5586 1           dispatch[CURLYX][REG_ANY] = compare_left_curly;
5587 1           dispatch[WHILEM][REG_ANY] = compare_left_tail;
5588 1           dispatch[OPEN][REG_ANY] = compare_left_open;
5589 1           dispatch[CLOSE][REG_ANY] = compare_left_tail;
5590 1           dispatch[IFMATCH][REG_ANY] = compare_after_assertion;
5591 1           dispatch[UNLESSM][REG_ANY] = compare_after_assertion;
5592 1           dispatch[OPFAIL][REG_ANY] = compare_after_alt_assertion;
5593 1           dispatch[MINMOD][REG_ANY] = compare_left_tail;
5594 1           dispatch[LNBREAK][REG_ANY] = compare_mismatch;
5595 1           dispatch[LOOKBEHIND_END][REG_ANY] = compare_left_tail;
5596 1           dispatch[OPTIMIZED][REG_ANY] = compare_left_tail;
5597              
5598 1           dispatch[SUCCEED][SANY] = compare_left_tail;
5599 1           dispatch[MBOL][SANY] = compare_bol;
5600 1           dispatch[SBOL][SANY] = compare_bol;
5601 1           dispatch[BOUND][SANY] = compare_mismatch;
5602 1           dispatch[NBOUND][SANY] = compare_mismatch;
5603 1           dispatch[REG_ANY][SANY] = compare_tails;
5604 1           dispatch[SANY][SANY] = compare_tails;
5605 1           dispatch[ANYOF][SANY] = compare_tails;
5606 1           dispatch[ANYOFD][SANY] = compare_tails;
5607 1           dispatch[ANYOFR][SANY] = compare_tails;
5608 1           dispatch[ANYOFM][SANY] = compare_tails;
5609 1           dispatch[NANYOFM][SANY] = compare_tails;
5610 1           dispatch[POSIXD][SANY] = compare_tails;
5611 1           dispatch[POSIXU][SANY] = compare_tails;
5612 1           dispatch[POSIXA][SANY] = compare_tails;
5613 1           dispatch[NPOSIXD][SANY] = compare_tails;
5614 1           dispatch[NPOSIXU][SANY] = compare_tails;
5615 1           dispatch[NPOSIXA][SANY] = compare_tails;
5616 1           dispatch[BRANCH][SANY] = compare_left_branch;
5617 1           dispatch[EXACT][SANY] = compare_tails;
5618 1           dispatch[EXACTF][SANY] = compare_tails;
5619 1           dispatch[EXACTFU][SANY] = compare_tails;
5620 1           dispatch[NOTHING][SANY] = compare_left_tail;
5621 1           dispatch[TAIL][SANY] = compare_left_tail;
5622 1           dispatch[STAR][SANY] = compare_mismatch;
5623 1           dispatch[PLUS][SANY] = compare_left_plus;
5624 1           dispatch[CURLY][SANY] = compare_left_curly;
5625 1           dispatch[CURLYM][SANY] = compare_left_curly;
5626 1           dispatch[CURLYX][SANY] = compare_left_curly;
5627 1           dispatch[WHILEM][SANY] = compare_left_tail;
5628 1           dispatch[OPEN][SANY] = compare_left_open;
5629 1           dispatch[CLOSE][SANY] = compare_left_tail;
5630 1           dispatch[IFMATCH][SANY] = compare_after_assertion;
5631 1           dispatch[UNLESSM][SANY] = compare_after_assertion;
5632 1           dispatch[OPFAIL][SANY] = compare_after_alt_assertion;
5633 1           dispatch[MINMOD][SANY] = compare_left_tail;
5634 1           dispatch[LNBREAK][SANY] = compare_mismatch;
5635 1           dispatch[LOOKBEHIND_END][SANY] = compare_left_tail;
5636 1           dispatch[OPTIMIZED][SANY] = compare_left_tail;
5637              
5638 1           dispatch[SUCCEED][ANYOF] = compare_left_tail;
5639 1           dispatch[MBOL][ANYOF] = compare_bol;
5640 1           dispatch[SBOL][ANYOF] = compare_bol;
5641 1           dispatch[BOUND][ANYOF] = compare_mismatch;
5642 1           dispatch[NBOUND][ANYOF] = compare_mismatch;
5643 1           dispatch[REG_ANY][ANYOF] = compare_reg_any_anyof;
5644 1           dispatch[SANY][ANYOF] = compare_sany_anyof;
5645 1           dispatch[ANYOF][ANYOF] = compare_anyof_anyof;
5646 1           dispatch[ANYOFD][ANYOF] = compare_anyof_anyof;
5647 1           dispatch[ANYOFR][ANYOF] = compare_anyofr_anyof;
5648 1           dispatch[ANYOFM][ANYOF] = compare_anyofm_anyof;
5649 1           dispatch[NANYOFM][ANYOF] = compare_mismatch;
5650 1           dispatch[POSIXD][ANYOF] = compare_posix_anyof;
5651 1           dispatch[POSIXU][ANYOF] = compare_posix_anyof;
5652 1           dispatch[POSIXA][ANYOF] = compare_posix_anyof;
5653 1           dispatch[NPOSIXD][ANYOF] = compare_negative_posix_anyof;
5654 1           dispatch[NPOSIXU][ANYOF] = compare_negative_posix_anyof;
5655 1           dispatch[NPOSIXA][ANYOF] = compare_negative_posix_anyof;
5656 1           dispatch[BRANCH][ANYOF] = compare_left_branch;
5657 1           dispatch[EXACT][ANYOF] = compare_exact_anyof;
5658 1           dispatch[EXACTF][ANYOF] = compare_exactf_anyof;
5659 1           dispatch[EXACTFU][ANYOF] = compare_exactf_anyof;
5660 1           dispatch[NOTHING][ANYOF] = compare_left_tail;
5661 1           dispatch[TAIL][ANYOF] = compare_left_tail;
5662 1           dispatch[STAR][ANYOF] = compare_mismatch;
5663 1           dispatch[PLUS][ANYOF] = compare_left_plus;
5664 1           dispatch[CURLY][ANYOF] = compare_left_curly;
5665 1           dispatch[CURLYM][ANYOF] = compare_left_curly;
5666 1           dispatch[CURLYX][ANYOF] = compare_left_curly;
5667 1           dispatch[WHILEM][ANYOF] = compare_left_tail;
5668 1           dispatch[OPEN][ANYOF] = compare_left_open;
5669 1           dispatch[CLOSE][ANYOF] = compare_left_tail;
5670 1           dispatch[IFMATCH][ANYOF] = compare_after_assertion;
5671 1           dispatch[UNLESSM][ANYOF] = compare_after_assertion;
5672 1           dispatch[OPFAIL][ANYOF] = compare_after_alt_assertion;
5673 1           dispatch[MINMOD][ANYOF] = compare_left_tail;
5674 1           dispatch[LNBREAK][ANYOF] = compare_mismatch;
5675 1           dispatch[LOOKBEHIND_END][ANYOF] = compare_left_tail;
5676 1           dispatch[OPTIMIZED][ANYOF] = compare_left_tail;
5677              
5678 1           dispatch[SUCCEED][ANYOFD] = compare_left_tail;
5679 1           dispatch[MBOL][ANYOFD] = compare_bol;
5680 1           dispatch[SBOL][ANYOFD] = compare_bol;
5681 1           dispatch[BOUND][ANYOFD] = compare_mismatch;
5682 1           dispatch[NBOUND][ANYOFD] = compare_mismatch;
5683 1           dispatch[REG_ANY][ANYOFD] = compare_reg_any_anyof;
5684 1           dispatch[SANY][ANYOFD] = compare_sany_anyof;
5685 1           dispatch[ANYOF][ANYOFD] = compare_anyof_anyof;
5686 1           dispatch[ANYOFD][ANYOFD] = compare_anyof_anyof;
5687 1           dispatch[ANYOFR][ANYOFD] = compare_anyofr_anyof;
5688 1           dispatch[ANYOFM][ANYOFD] = compare_anyofm_anyof;
5689 1           dispatch[NANYOFM][ANYOFD] = compare_mismatch;
5690 1           dispatch[POSIXD][ANYOFD] = compare_posix_anyof;
5691 1           dispatch[POSIXU][ANYOFD] = compare_posix_anyof;
5692 1           dispatch[POSIXA][ANYOFD] = compare_posix_anyof;
5693 1           dispatch[NPOSIXD][ANYOFD] = compare_negative_posix_anyof;
5694 1           dispatch[NPOSIXU][ANYOFD] = compare_negative_posix_anyof;
5695 1           dispatch[NPOSIXA][ANYOFD] = compare_negative_posix_anyof;
5696 1           dispatch[BRANCH][ANYOFD] = compare_left_branch;
5697 1           dispatch[EXACT][ANYOFD] = compare_exact_anyof;
5698 1           dispatch[EXACTFU][ANYOFD] = compare_exactf_anyof;
5699 1           dispatch[NOTHING][ANYOFD] = compare_left_tail;
5700 1           dispatch[TAIL][ANYOFD] = compare_left_tail;
5701 1           dispatch[STAR][ANYOFD] = compare_mismatch;
5702 1           dispatch[PLUS][ANYOFD] = compare_left_plus;
5703 1           dispatch[CURLY][ANYOFD] = compare_left_curly;
5704 1           dispatch[CURLYM][ANYOFD] = compare_left_curly;
5705 1           dispatch[CURLYX][ANYOFD] = compare_left_curly;
5706 1           dispatch[OPEN][ANYOFD] = compare_left_open;
5707 1           dispatch[CLOSE][ANYOFD] = compare_left_tail;
5708 1           dispatch[IFMATCH][ANYOFD] = compare_after_assertion;
5709 1           dispatch[UNLESSM][ANYOFD] = compare_after_assertion;
5710 1           dispatch[OPFAIL][ANYOFD] = compare_after_alt_assertion;
5711 1           dispatch[MINMOD][ANYOFD] = compare_left_tail;
5712 1           dispatch[LNBREAK][ANYOFD] = compare_mismatch;
5713 1           dispatch[LOOKBEHIND_END][ANYOFD] = compare_left_tail;
5714 1           dispatch[OPTIMIZED][ANYOFD] = compare_left_tail;
5715              
5716 1           dispatch[SUCCEED][ANYOFR] = compare_left_tail;
5717 1           dispatch[MBOL][ANYOFR] = compare_bol;
5718 1           dispatch[SBOL][ANYOFR] = compare_bol;
5719 1           dispatch[BOUND][ANYOFR] = compare_mismatch;
5720 1           dispatch[NBOUND][ANYOFR] = compare_mismatch;
5721 1           dispatch[REG_ANY][ANYOFR] = compare_mismatch;
5722 1           dispatch[SANY][ANYOFR] = compare_mismatch;
5723 1           dispatch[ANYOF][ANYOFR] = compare_anyof_anyofr;
5724 1           dispatch[ANYOFR][ANYOFR] = compare_anyofr_anyofr;
5725 1           dispatch[ANYOFM][ANYOFR] = compare_anyofm_anyofr;
5726 1           dispatch[NANYOFM][ANYOFR] = compare_mismatch;
5727 1           dispatch[POSIXD][ANYOFR] = compare_mismatch;
5728 1           dispatch[POSIXU][ANYOFR] = compare_mismatch;
5729 1           dispatch[POSIXA][ANYOFR] = compare_mismatch;
5730 1           dispatch[NPOSIXD][ANYOFR] = compare_mismatch;
5731 1           dispatch[NPOSIXU][ANYOFR] = compare_mismatch;
5732 1           dispatch[NPOSIXA][ANYOFR] = compare_mismatch;
5733 1           dispatch[BRANCH][ANYOFR] = compare_left_branch;
5734 1           dispatch[EXACT][ANYOFR] = compare_exact_anyofr;
5735 1           dispatch[EXACTF][ANYOFR] = compare_exactf_anyofr;
5736 1           dispatch[EXACTFU][ANYOFR] = compare_exactf_anyofr;
5737 1           dispatch[NOTHING][ANYOFR] = compare_left_tail;
5738 1           dispatch[TAIL][ANYOFR] = compare_left_tail;
5739 1           dispatch[STAR][ANYOFR] = compare_mismatch;
5740 1           dispatch[PLUS][ANYOFR] = compare_left_plus;
5741 1           dispatch[CURLY][ANYOFR] = compare_left_curly;
5742 1           dispatch[CURLYM][ANYOFR] = compare_left_curly;
5743 1           dispatch[CURLYX][ANYOFR] = compare_left_curly;
5744 1           dispatch[OPEN][ANYOFR] = compare_left_open;
5745 1           dispatch[CLOSE][ANYOFR] = compare_left_tail;
5746 1           dispatch[IFMATCH][ANYOFR] = compare_after_assertion;
5747 1           dispatch[UNLESSM][ANYOFR] = compare_after_assertion;
5748 1           dispatch[OPFAIL][ANYOFR] = compare_after_alt_assertion;
5749 1           dispatch[MINMOD][ANYOFR] = compare_left_tail;
5750 1           dispatch[LNBREAK][ANYOFR] = compare_mismatch;
5751 1           dispatch[LOOKBEHIND_END][ANYOFR] = compare_left_tail;
5752 1           dispatch[OPTIMIZED][ANYOFR] = compare_left_tail;
5753              
5754 1           dispatch[SUCCEED][ANYOFM] = compare_left_tail;
5755 1           dispatch[MBOL][ANYOFM] = compare_bol;
5756 1           dispatch[SBOL][ANYOFM] = compare_bol;
5757 1           dispatch[BOUND][ANYOFM] = compare_mismatch;
5758 1           dispatch[NBOUND][ANYOFM] = compare_mismatch;
5759 1           dispatch[REG_ANY][ANYOFM] = compare_mismatch;
5760 1           dispatch[SANY][ANYOFM] = compare_mismatch;
5761 1           dispatch[ANYOF][ANYOFM] = compare_anyof_anyofm;
5762 1           dispatch[ANYOFD][ANYOFM] = compare_anyof_anyofm;
5763 1           dispatch[ANYOFR][ANYOFM] = compare_anyofr_anyofm;
5764 1           dispatch[ANYOFM][ANYOFM] = compare_anyofm_anyofm;
5765 1           dispatch[NANYOFM][ANYOFM] = compare_mismatch;
5766 1           dispatch[POSIXD][ANYOFM] = compare_mismatch;
5767 1           dispatch[POSIXU][ANYOFM] = compare_mismatch;
5768 1           dispatch[POSIXA][ANYOFM] = compare_mismatch;
5769 1           dispatch[NPOSIXD][ANYOFM] = compare_mismatch;
5770 1           dispatch[NPOSIXU][ANYOFM] = compare_mismatch;
5771 1           dispatch[NPOSIXA][ANYOFM] = compare_mismatch;
5772 1           dispatch[BRANCH][ANYOFM] = compare_left_branch;
5773 1           dispatch[EXACT][ANYOFM] = compare_exact_anyofm;
5774 1           dispatch[EXACTF][ANYOFM] = compare_exactf_anyofm;
5775 1           dispatch[EXACTFU][ANYOFM] = compare_exactf_anyofm;
5776 1           dispatch[NOTHING][ANYOFM] = compare_left_tail;
5777 1           dispatch[TAIL][ANYOFM] = compare_left_tail;
5778 1           dispatch[STAR][ANYOFM] = compare_mismatch;
5779 1           dispatch[PLUS][ANYOFM] = compare_left_plus;
5780 1           dispatch[CURLY][ANYOFM] = compare_left_curly;
5781 1           dispatch[CURLYM][ANYOFM] = compare_left_curly;
5782 1           dispatch[CURLYX][ANYOFM] = compare_left_curly;
5783 1           dispatch[OPEN][ANYOFM] = compare_left_open;
5784 1           dispatch[CLOSE][ANYOFM] = compare_left_tail;
5785 1           dispatch[IFMATCH][ANYOFM] = compare_after_assertion;
5786 1           dispatch[UNLESSM][ANYOFM] = compare_after_assertion;
5787 1           dispatch[OPFAIL][ANYOFM] = compare_after_alt_assertion;
5788 1           dispatch[MINMOD][ANYOFM] = compare_left_tail;
5789 1           dispatch[LNBREAK][ANYOFM] = compare_mismatch;
5790 1           dispatch[LOOKBEHIND_END][ANYOFM] = compare_left_tail;
5791 1           dispatch[OPTIMIZED][ANYOFM] = compare_left_tail;
5792              
5793 1           dispatch[SUCCEED][NANYOFM] = compare_left_tail;
5794 1           dispatch[MBOL][NANYOFM] = compare_bol;
5795 1           dispatch[SBOL][NANYOFM] = compare_bol;
5796 1           dispatch[BOUND][NANYOFM] = compare_mismatch;
5797 1           dispatch[NBOUND][NANYOFM] = compare_mismatch;
5798 1           dispatch[REG_ANY][NANYOFM] = compare_mismatch;
5799 1           dispatch[SANY][NANYOFM] = compare_mismatch;
5800 1           dispatch[ANYOF][NANYOFM] = compare_anyof_nanyofm;
5801 1           dispatch[ANYOFD][NANYOFM] = compare_anyof_nanyofm;
5802 1           dispatch[ANYOFR][NANYOFM] = compare_anyofr_nanyofm;
5803 1           dispatch[ANYOFM][NANYOFM] = compare_anyofm_nanyofm;
5804 1           dispatch[NANYOFM][NANYOFM] = compare_nanyofm_nanyofm;
5805 1           dispatch[POSIXD][NANYOFM] = compare_posix_nanyofm;
5806 1           dispatch[POSIXU][NANYOFM] = compare_posix_nanyofm;
5807 1           dispatch[POSIXA][NANYOFM] = compare_posix_nanyofm;
5808 1           dispatch[NPOSIXD][NANYOFM] = compare_negative_posix_nanyofm;
5809 1           dispatch[NPOSIXU][NANYOFM] = compare_negative_posix_nanyofm;
5810 1           dispatch[NPOSIXA][NANYOFM] = compare_negative_posix_nanyofm;
5811 1           dispatch[BRANCH][NANYOFM] = compare_left_branch;
5812 1           dispatch[EXACT][NANYOFM] = compare_exact_nanyofm;
5813 1           dispatch[EXACTF][NANYOFM] = compare_exactf_nanyofm;
5814 1           dispatch[EXACTFU][NANYOFM] = compare_exactf_nanyofm;
5815 1           dispatch[NOTHING][NANYOFM] = compare_left_tail;
5816 1           dispatch[TAIL][NANYOFM] = compare_left_tail;
5817 1           dispatch[STAR][NANYOFM] = compare_mismatch;
5818 1           dispatch[PLUS][NANYOFM] = compare_left_plus;
5819 1           dispatch[CURLY][NANYOFM] = compare_left_curly;
5820 1           dispatch[CURLYM][NANYOFM] = compare_left_curly;
5821 1           dispatch[CURLYX][NANYOFM] = compare_left_curly;
5822 1           dispatch[OPEN][NANYOFM] = compare_left_open;
5823 1           dispatch[CLOSE][NANYOFM] = compare_left_tail;
5824 1           dispatch[IFMATCH][NANYOFM] = compare_after_assertion;
5825 1           dispatch[UNLESSM][NANYOFM] = compare_after_assertion;
5826 1           dispatch[OPFAIL][NANYOFM] = compare_after_alt_assertion;
5827 1           dispatch[MINMOD][NANYOFM] = compare_left_tail;
5828 1           dispatch[LNBREAK][NANYOFM] = compare_mismatch;
5829 1           dispatch[LOOKBEHIND_END][NANYOFM] = compare_left_tail;
5830 1           dispatch[OPTIMIZED][NANYOFM] = compare_left_tail;
5831              
5832 1           dispatch[SUCCEED][POSIXD] = compare_left_tail;
5833 1           dispatch[MBOL][POSIXD] = compare_bol;
5834 1           dispatch[SBOL][POSIXD] = compare_bol;
5835 1           dispatch[BOUND][POSIXD] = compare_mismatch;
5836 1           dispatch[NBOUND][POSIXD] = compare_mismatch;
5837 1           dispatch[REG_ANY][POSIXD] = compare_mismatch;
5838 1           dispatch[SANY][POSIXD] = compare_mismatch;
5839 1           dispatch[ANYOF][POSIXD] = compare_anyof_posix;
5840 1           dispatch[ANYOFD][POSIXD] = compare_anyof_posix;
5841 1           dispatch[ANYOFR][POSIXD] = compare_anyofr_posix;
5842 1           dispatch[ANYOFM][POSIXD] = compare_anyofm_posix;
5843 1           dispatch[NANYOFM][POSIXD] = compare_nanyofm_posix;
5844 1           dispatch[POSIXD][POSIXD] = compare_posix_posix;
5845 1           dispatch[POSIXU][POSIXD] = compare_posix_posix;
5846 1           dispatch[POSIXA][POSIXD] = compare_posix_posix;
5847 1           dispatch[NPOSIXD][POSIXD] = compare_mismatch;
5848 1           dispatch[NPOSIXU][POSIXD] = compare_mismatch;
5849 1           dispatch[NPOSIXA][POSIXD] = compare_mismatch;
5850 1           dispatch[BRANCH][POSIXD] = compare_left_branch;
5851 1           dispatch[EXACT][POSIXD] = compare_exact_posix;
5852 1           dispatch[EXACTF][POSIXD] = compare_exactf_posix;
5853 1           dispatch[EXACTFU][POSIXD] = compare_exactf_posix;
5854 1           dispatch[NOTHING][POSIXD] = compare_left_tail;
5855 1           dispatch[STAR][POSIXD] = compare_mismatch;
5856 1           dispatch[PLUS][POSIXD] = compare_left_plus;
5857 1           dispatch[CURLY][POSIXD] = compare_left_curly;
5858 1           dispatch[CURLYM][POSIXD] = compare_left_curly;
5859 1           dispatch[CURLYX][POSIXD] = compare_left_curly;
5860 1           dispatch[OPEN][POSIXD] = compare_left_open;
5861 1           dispatch[CLOSE][POSIXD] = compare_left_tail;
5862 1           dispatch[IFMATCH][POSIXD] = compare_after_assertion;
5863 1           dispatch[UNLESSM][POSIXD] = compare_after_assertion;
5864 1           dispatch[OPFAIL][POSIXD] = compare_after_alt_assertion;
5865 1           dispatch[MINMOD][POSIXD] = compare_left_tail;
5866 1           dispatch[LNBREAK][POSIXD] = compare_mismatch;
5867 1           dispatch[LOOKBEHIND_END][POSIXD] = compare_left_tail;
5868 1           dispatch[OPTIMIZED][POSIXD] = compare_left_tail;
5869              
5870 1           dispatch[SUCCEED][POSIXU] = compare_left_tail;
5871 1           dispatch[MBOL][POSIXU] = compare_bol;
5872 1           dispatch[SBOL][POSIXU] = compare_bol;
5873 1           dispatch[BOUND][POSIXU] = compare_mismatch;
5874 1           dispatch[NBOUND][POSIXU] = compare_mismatch;
5875 1           dispatch[REG_ANY][POSIXU] = compare_mismatch;
5876 1           dispatch[SANY][POSIXU] = compare_mismatch;
5877 1           dispatch[ANYOF][POSIXU] = compare_anyof_posix;
5878 1           dispatch[ANYOFD][POSIXU] = compare_anyof_posix;
5879 1           dispatch[ANYOFR][POSIXU] = compare_anyofr_posix;
5880 1           dispatch[ANYOFM][POSIXU] = compare_anyofm_posix;
5881 1           dispatch[NANYOFM][POSIXU] = compare_nanyofm_posix;
5882 1           dispatch[POSIXD][POSIXU] = compare_posix_posix;
5883 1           dispatch[POSIXA][POSIXU] = compare_posix_posix;
5884 1           dispatch[POSIXU][POSIXU] = compare_posix_posix;
5885 1           dispatch[NPOSIXD][POSIXU] = compare_mismatch;
5886 1           dispatch[NPOSIXU][POSIXU] = compare_mismatch;
5887 1           dispatch[NPOSIXA][POSIXU] = compare_mismatch;
5888 1           dispatch[BRANCH][POSIXU] = compare_left_branch;
5889 1           dispatch[EXACT][POSIXU] = compare_exact_posix;
5890 1           dispatch[EXACTF][POSIXU] = compare_exact_posix;
5891 1           dispatch[EXACTFU][POSIXU] = compare_exact_posix;
5892 1           dispatch[NOTHING][POSIXU] = compare_left_tail;
5893 1           dispatch[TAIL][POSIXU] = compare_left_tail;
5894 1           dispatch[STAR][POSIXU] = compare_mismatch;
5895 1           dispatch[PLUS][POSIXU] = compare_left_plus;
5896 1           dispatch[CURLY][POSIXU] = compare_left_curly;
5897 1           dispatch[CURLYM][POSIXU] = compare_left_curly;
5898 1           dispatch[CURLYX][POSIXU] = compare_left_curly;
5899 1           dispatch[OPEN][POSIXU] = compare_left_open;
5900 1           dispatch[CLOSE][POSIXU] = compare_left_tail;
5901 1           dispatch[IFMATCH][POSIXU] = compare_after_assertion;
5902 1           dispatch[UNLESSM][POSIXU] = compare_after_assertion;
5903 1           dispatch[OPFAIL][POSIXU] = compare_after_alt_assertion;
5904 1           dispatch[MINMOD][POSIXU] = compare_left_tail;
5905 1           dispatch[LNBREAK][POSIXU] = compare_mismatch;
5906 1           dispatch[LOOKBEHIND_END][POSIXU] = compare_left_tail;
5907 1           dispatch[OPTIMIZED][POSIXU] = compare_left_tail;
5908              
5909 1           dispatch[SUCCEED][POSIXA] = compare_left_tail;
5910 1           dispatch[MBOL][POSIXA] = compare_bol;
5911 1           dispatch[SBOL][POSIXA] = compare_bol;
5912 1           dispatch[BOUND][POSIXA] = compare_mismatch;
5913 1           dispatch[NBOUND][POSIXA] = compare_mismatch;
5914 1           dispatch[REG_ANY][POSIXA] = compare_mismatch;
5915 1           dispatch[SANY][POSIXA] = compare_mismatch;
5916 1           dispatch[ANYOF][POSIXA] = compare_anyof_posixa;
5917 1           dispatch[ANYOFD][POSIXA] = compare_anyof_posixa;
5918 1           dispatch[ANYOFR][POSIXA] = compare_anyofr_posix;
5919 1           dispatch[ANYOFM][POSIXA] = compare_anyofm_posix;
5920 1           dispatch[NANYOFM][POSIXA] = compare_nanyofm_posix;
5921 1           dispatch[POSIXD][POSIXA] = compare_mismatch;
5922 1           dispatch[POSIXU][POSIXA] = compare_mismatch;
5923 1           dispatch[POSIXA][POSIXA] = compare_posix_posix;
5924 1           dispatch[NPOSIXD][POSIXA] = compare_mismatch;
5925 1           dispatch[NPOSIXU][POSIXA] = compare_mismatch;
5926 1           dispatch[NPOSIXA][POSIXA] = compare_mismatch;
5927 1           dispatch[BRANCH][POSIXA] = compare_left_branch;
5928 1           dispatch[EXACT][POSIXA] = compare_exact_posix;
5929 1           dispatch[EXACTF][POSIXA] = compare_exact_posix;
5930 1           dispatch[EXACTFU][POSIXA] = compare_exact_posix;
5931 1           dispatch[NOTHING][POSIXA] = compare_left_tail;
5932 1           dispatch[STAR][POSIXA] = compare_mismatch;
5933 1           dispatch[PLUS][POSIXA] = compare_left_plus;
5934 1           dispatch[CURLY][POSIXA] = compare_left_curly;
5935 1           dispatch[CURLYM][POSIXA] = compare_left_curly;
5936 1           dispatch[CURLYX][POSIXA] = compare_left_curly;
5937 1           dispatch[OPEN][POSIXA] = compare_left_open;
5938 1           dispatch[CLOSE][POSIXA] = compare_left_tail;
5939 1           dispatch[IFMATCH][POSIXA] = compare_after_assertion;
5940 1           dispatch[UNLESSM][POSIXA] = compare_after_assertion;
5941 1           dispatch[OPFAIL][POSIXA] = compare_after_alt_assertion;
5942 1           dispatch[MINMOD][POSIXA] = compare_left_tail;
5943 1           dispatch[LNBREAK][POSIXA] = compare_mismatch;
5944 1           dispatch[LOOKBEHIND_END][POSIXA] = compare_left_tail;
5945 1           dispatch[OPTIMIZED][POSIXA] = compare_left_tail;
5946              
5947 1           dispatch[SUCCEED][NPOSIXD] = compare_left_tail;
5948 1           dispatch[MBOL][NPOSIXD] = compare_bol;
5949 1           dispatch[SBOL][NPOSIXD] = compare_bol;
5950 1           dispatch[BOUND][NPOSIXD] = compare_mismatch;
5951 1           dispatch[NBOUND][NPOSIXD] = compare_mismatch;
5952 1           dispatch[REG_ANY][NPOSIXD] = compare_mismatch;
5953 1           dispatch[SANY][NPOSIXD] = compare_mismatch;
5954 1           dispatch[ANYOF][NPOSIXD] = compare_anyof_negative_posix;
5955 1           dispatch[ANYOFD][NPOSIXD] = compare_anyof_negative_posix;
5956 1           dispatch[ANYOFR][NPOSIXD] = compare_anyofr_negative_posix;
5957 1           dispatch[ANYOFM][NPOSIXD] = compare_anyofm_negative_posix;
5958 1           dispatch[NANYOFM][NPOSIXD] = compare_nanyofm_negative_posix;
5959 1           dispatch[POSIXD][NPOSIXD] = compare_posix_negative_posix;
5960 1           dispatch[POSIXU][NPOSIXD] = compare_posix_negative_posix;
5961 1           dispatch[POSIXA][NPOSIXD] = compare_posix_negative_posix;
5962 1           dispatch[NPOSIXD][NPOSIXD] = compare_negative_posix_negative_posix;
5963 1           dispatch[NPOSIXU][NPOSIXD] = compare_negative_posix_negative_posix;
5964 1           dispatch[NPOSIXA][NPOSIXD] = compare_mismatch;
5965 1           dispatch[BRANCH][NPOSIXD] = compare_left_branch;
5966 1           dispatch[EXACT][NPOSIXD] = compare_exact_negative_posix;
5967 1           dispatch[EXACTF][NPOSIXD] = compare_exactf_negative_posix;
5968 1           dispatch[EXACTFU][NPOSIXD] = compare_exactf_negative_posix;
5969 1           dispatch[NOTHING][NPOSIXD] = compare_left_tail;
5970 1           dispatch[STAR][NPOSIXD] = compare_mismatch;
5971 1           dispatch[PLUS][NPOSIXD] = compare_left_plus;
5972 1           dispatch[CURLY][NPOSIXD] = compare_left_curly;
5973 1           dispatch[CURLYM][NPOSIXD] = compare_left_curly;
5974 1           dispatch[CURLYX][NPOSIXD] = compare_left_curly;
5975 1           dispatch[OPEN][NPOSIXD] = compare_left_open;
5976 1           dispatch[CLOSE][NPOSIXD] = compare_left_tail;
5977 1           dispatch[IFMATCH][NPOSIXD] = compare_after_assertion;
5978 1           dispatch[UNLESSM][NPOSIXD] = compare_after_assertion;
5979 1           dispatch[OPFAIL][NPOSIXD] = compare_after_alt_assertion;
5980 1           dispatch[MINMOD][NPOSIXD] = compare_left_tail;
5981 1           dispatch[LNBREAK][NPOSIXD] = compare_mismatch;
5982 1           dispatch[LOOKBEHIND_END][NPOSIXD] = compare_left_tail;
5983 1           dispatch[OPTIMIZED][NPOSIXD] = compare_left_tail;
5984              
5985 1           dispatch[SUCCEED][NPOSIXU] = compare_left_tail;
5986 1           dispatch[MBOL][NPOSIXU] = compare_bol;
5987 1           dispatch[SBOL][NPOSIXU] = compare_bol;
5988 1           dispatch[BOUND][NPOSIXU] = compare_mismatch;
5989 1           dispatch[NBOUND][NPOSIXU] = compare_mismatch;
5990 1           dispatch[REG_ANY][NPOSIXU] = compare_mismatch;
5991 1           dispatch[SANY][NPOSIXU] = compare_mismatch;
5992 1           dispatch[ANYOF][NPOSIXU] = compare_anyof_negative_posix;
5993 1           dispatch[ANYOFD][NPOSIXU] = compare_anyof_negative_posix;
5994 1           dispatch[ANYOFR][NPOSIXU] = compare_anyofr_negative_posix;
5995 1           dispatch[ANYOFM][NPOSIXU] = compare_anyofm_negative_posix;
5996 1           dispatch[NANYOFM][NPOSIXU] = compare_nanyofm_negative_posix;
5997 1           dispatch[POSIXD][NPOSIXU] = compare_posix_negative_posix;
5998 1           dispatch[POSIXU][NPOSIXU] = compare_posix_negative_posix;
5999 1           dispatch[POSIXA][NPOSIXU] = compare_posix_negative_posix;
6000 1           dispatch[NPOSIXD][NPOSIXU] = compare_negative_posix_negative_posix;
6001 1           dispatch[NPOSIXU][NPOSIXU] = compare_negative_posix_negative_posix;
6002 1           dispatch[NPOSIXA][NPOSIXU] = compare_mismatch;
6003 1           dispatch[BRANCH][NPOSIXU] = compare_left_branch;
6004 1           dispatch[EXACT][NPOSIXU] = compare_exact_negative_posix;
6005 1           dispatch[EXACTF][NPOSIXU] = compare_exactf_negative_posix;
6006 1           dispatch[EXACTFU][NPOSIXU] = compare_exactf_negative_posix;
6007 1           dispatch[NOTHING][NPOSIXU] = compare_left_tail;
6008 1           dispatch[STAR][NPOSIXU] = compare_mismatch;
6009 1           dispatch[PLUS][NPOSIXU] = compare_left_plus;
6010 1           dispatch[CURLY][NPOSIXU] = compare_left_curly;
6011 1           dispatch[CURLYM][NPOSIXU] = compare_left_curly;
6012 1           dispatch[CURLYX][NPOSIXU] = compare_left_curly;
6013 1           dispatch[OPEN][NPOSIXU] = compare_left_open;
6014 1           dispatch[CLOSE][NPOSIXU] = compare_left_tail;
6015 1           dispatch[IFMATCH][NPOSIXU] = compare_after_assertion;
6016 1           dispatch[UNLESSM][NPOSIXU] = compare_after_assertion;
6017 1           dispatch[OPFAIL][NPOSIXU] = compare_after_alt_assertion;
6018 1           dispatch[MINMOD][NPOSIXU] = compare_left_tail;
6019 1           dispatch[LNBREAK][NPOSIXU] = compare_mismatch;
6020 1           dispatch[LOOKBEHIND_END][NPOSIXU] = compare_left_tail;
6021 1           dispatch[OPTIMIZED][NPOSIXU] = compare_left_tail;
6022              
6023 1           dispatch[SUCCEED][NPOSIXA] = compare_left_tail;
6024 1           dispatch[MBOL][NPOSIXA] = compare_bol;
6025 1           dispatch[SBOL][NPOSIXA] = compare_bol;
6026 1           dispatch[BOUND][NPOSIXA] = compare_mismatch;
6027 1           dispatch[NBOUND][NPOSIXA] = compare_mismatch;
6028 1           dispatch[REG_ANY][NPOSIXA] = compare_mismatch;
6029 1           dispatch[SANY][NPOSIXA] = compare_mismatch;
6030 1           dispatch[ANYOF][NPOSIXA] = compare_anyof_negative_posix;
6031 1           dispatch[ANYOFD][NPOSIXA] = compare_anyof_negative_posix;
6032 1           dispatch[ANYOFR][NPOSIXA] = compare_anyofr_negative_posix;
6033 1           dispatch[ANYOFM][NPOSIXA] = compare_anyofm_negative_posix;
6034 1           dispatch[NANYOFM][NPOSIXA] = compare_nanyofm_negative_posix;
6035 1           dispatch[POSIXD][NPOSIXA] = compare_posix_negative_posix;
6036 1           dispatch[POSIXU][NPOSIXA] = compare_posix_negative_posix;
6037 1           dispatch[POSIXA][NPOSIXA] = compare_posix_negative_posix;
6038 1           dispatch[NPOSIXD][NPOSIXA] = compare_negative_posix_negative_posix;
6039 1           dispatch[NPOSIXU][NPOSIXA] = compare_negative_posix_negative_posix;
6040 1           dispatch[NPOSIXA][NPOSIXA] = compare_negative_posix_negative_posix;
6041 1           dispatch[BRANCH][NPOSIXA] = compare_left_branch;
6042 1           dispatch[EXACT][NPOSIXA] = compare_exact_negative_posix;
6043 1           dispatch[EXACTF][NPOSIXA] = compare_exactf_negative_posix;
6044 1           dispatch[EXACTFU][NPOSIXA] = compare_exactf_negative_posix;
6045 1           dispatch[NOTHING][NPOSIXA] = compare_left_tail;
6046 1           dispatch[STAR][NPOSIXA] = compare_mismatch;
6047 1           dispatch[PLUS][NPOSIXA] = compare_left_plus;
6048 1           dispatch[CURLY][NPOSIXA] = compare_left_curly;
6049 1           dispatch[CURLYM][NPOSIXA] = compare_left_curly;
6050 1           dispatch[CURLYX][NPOSIXA] = compare_left_curly;
6051 1           dispatch[OPEN][NPOSIXA] = compare_left_open;
6052 1           dispatch[CLOSE][NPOSIXA] = compare_left_tail;
6053 1           dispatch[IFMATCH][NPOSIXA] = compare_after_assertion;
6054 1           dispatch[UNLESSM][NPOSIXA] = compare_after_assertion;
6055 1           dispatch[OPFAIL][NPOSIXA] = compare_after_alt_assertion;
6056 1           dispatch[MINMOD][NPOSIXA] = compare_left_tail;
6057 1           dispatch[LNBREAK][NPOSIXA] = compare_mismatch;
6058 1           dispatch[LOOKBEHIND_END][NPOSIXA] = compare_left_tail;
6059 1           dispatch[OPTIMIZED][NPOSIXA] = compare_left_tail;
6060              
6061 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6062             {
6063 111           dispatch[i][BRANCH] = compare_right_branch;
6064             }
6065              
6066 1           dispatch[SUCCEED][BRANCH] = compare_left_tail;
6067 1           dispatch[ANYOF][BRANCH] = compare_anyof_branch;
6068 1           dispatch[ANYOFD][BRANCH] = compare_anyof_branch;
6069 1           dispatch[ANYOFR][BRANCH] = compare_anyofr_branch;
6070 1           dispatch[ANYOFM][BRANCH] = compare_anyofm_branch;
6071 1           dispatch[BRANCH][BRANCH] = compare_left_branch;
6072 1           dispatch[NOTHING][BRANCH] = compare_left_tail;
6073 1           dispatch[TAIL][BRANCH] = compare_left_tail;
6074 1           dispatch[WHILEM][BRANCH] = compare_left_tail;
6075 1           dispatch[OPEN][BRANCH] = compare_left_open;
6076 1           dispatch[CLOSE][BRANCH] = compare_left_tail;
6077 1           dispatch[IFMATCH][BRANCH] = compare_after_assertion;
6078 1           dispatch[UNLESSM][BRANCH] = compare_after_assertion;
6079 1           dispatch[OPFAIL][BRANCH] = compare_after_alt_assertion;
6080 1           dispatch[MINMOD][BRANCH] = compare_left_tail;
6081 1           dispatch[LOOKBEHIND_END][BRANCH] = compare_left_tail;
6082 1           dispatch[OPTIMIZED][BRANCH] = compare_left_tail;
6083              
6084 1           dispatch[SUCCEED][EXACT] = compare_left_tail;
6085 1           dispatch[MBOL][EXACT] = compare_bol;
6086 1           dispatch[SBOL][EXACT] = compare_bol;
6087 1           dispatch[BOUND][EXACT] = compare_mismatch;
6088 1           dispatch[NBOUND][EXACT] = compare_mismatch;
6089 1           dispatch[REG_ANY][EXACT] = compare_mismatch;
6090 1           dispatch[SANY][EXACT] = compare_mismatch;
6091 1           dispatch[ANYOF][EXACT] = compare_anyof_exact;
6092 1           dispatch[ANYOFD][EXACT] = compare_anyof_exact;
6093 1           dispatch[ANYOFR][EXACT] = compare_anyofr_exact;
6094 1           dispatch[ANYOFM][EXACT] = compare_anyofm_exact;
6095 1           dispatch[NANYOFM][EXACT] = compare_mismatch;
6096 1           dispatch[POSIXD][EXACT] = compare_mismatch;
6097 1           dispatch[POSIXU][EXACT] = compare_mismatch;
6098 1           dispatch[POSIXA][EXACT] = compare_mismatch;
6099 1           dispatch[NPOSIXD][EXACT] = compare_mismatch;
6100 1           dispatch[NPOSIXU][EXACT] = compare_mismatch;
6101 1           dispatch[NPOSIXA][EXACT] = compare_mismatch;
6102 1           dispatch[BRANCH][EXACT] = compare_left_branch;
6103 1           dispatch[EXACT][EXACT] = compare_exact_exact;
6104 1           dispatch[EXACTF][EXACT] = compare_exactf_exact;
6105 1           dispatch[EXACTFU][EXACT] = compare_exactf_exact;
6106 1           dispatch[NOTHING][EXACT] = compare_left_tail;
6107 1           dispatch[TAIL][EXACT] = compare_left_tail;
6108 1           dispatch[STAR][EXACT] = compare_mismatch;
6109 1           dispatch[PLUS][EXACT] = compare_left_plus;
6110 1           dispatch[CURLY][EXACT] = compare_left_curly;
6111 1           dispatch[CURLYM][EXACT] = compare_left_curly;
6112 1           dispatch[CURLYX][EXACT] = compare_left_curly;
6113 1           dispatch[WHILEM][EXACT] = compare_left_tail;
6114 1           dispatch[OPEN][EXACT] = compare_left_open;
6115 1           dispatch[CLOSE][EXACT] = compare_left_tail;
6116 1           dispatch[IFMATCH][EXACT] = compare_after_assertion;
6117 1           dispatch[UNLESSM][EXACT] = compare_after_assertion;
6118 1           dispatch[OPFAIL][EXACT] = compare_after_alt_assertion;
6119 1           dispatch[MINMOD][EXACT] = compare_left_tail;
6120 1           dispatch[LNBREAK][EXACT] = compare_mismatch;
6121 1           dispatch[LOOKBEHIND_END][EXACT] = compare_left_tail;
6122 1           dispatch[OPTIMIZED][EXACT] = compare_left_tail;
6123              
6124 1           dispatch[SUCCEED][EXACTF] = compare_left_tail;
6125 1           dispatch[MBOL][EXACTF] = compare_bol;
6126 1           dispatch[SBOL][EXACTF] = compare_bol;
6127 1           dispatch[BOUND][EXACTF] = compare_mismatch;
6128 1           dispatch[NBOUND][EXACTF] = compare_mismatch;
6129 1           dispatch[REG_ANY][EXACTF] = compare_mismatch;
6130 1           dispatch[SANY][EXACTF] = compare_mismatch;
6131 1           dispatch[ANYOF][EXACTF] = compare_anyof_exactf;
6132 1           dispatch[ANYOFD][EXACTF] = compare_anyof_exactf;
6133 1           dispatch[ANYOFR][EXACTF] = compare_anyofr_exactf;
6134 1           dispatch[ANYOFM][EXACTF] = compare_anyofm_exactf;
6135 1           dispatch[NANYOFM][EXACTF] = compare_mismatch;
6136 1           dispatch[POSIXD][EXACTF] = compare_mismatch;
6137 1           dispatch[POSIXU][EXACTF] = compare_mismatch;
6138 1           dispatch[POSIXA][EXACTF] = compare_mismatch;
6139 1           dispatch[NPOSIXD][EXACTF] = compare_mismatch;
6140 1           dispatch[NPOSIXU][EXACTF] = compare_mismatch;
6141 1           dispatch[NPOSIXA][EXACTF] = compare_mismatch;
6142 1           dispatch[BRANCH][EXACTF] = compare_left_branch;
6143 1           dispatch[EXACT][EXACTF] = compare_exact_exactf;
6144 1           dispatch[EXACTF][EXACTF] = compare_exactf_exactf;
6145 1           dispatch[NOTHING][EXACTF] = compare_left_tail;
6146 1           dispatch[TAIL][EXACTF] = compare_left_tail;
6147 1           dispatch[STAR][EXACTF] = compare_mismatch;
6148 1           dispatch[PLUS][EXACTF] = compare_left_plus;
6149 1           dispatch[CURLY][EXACTF] = compare_left_curly;
6150 1           dispatch[CURLYM][EXACTF] = compare_left_curly;
6151 1           dispatch[CURLYX][EXACTF] = compare_left_curly;
6152 1           dispatch[WHILEM][EXACTF] = compare_left_tail;
6153 1           dispatch[OPEN][EXACTF] = compare_left_open;
6154 1           dispatch[CLOSE][EXACTF] = compare_left_tail;
6155 1           dispatch[IFMATCH][EXACTF] = compare_after_assertion;
6156 1           dispatch[UNLESSM][EXACTF] = compare_after_assertion;
6157 1           dispatch[OPFAIL][EXACTF] = compare_after_alt_assertion;
6158 1           dispatch[MINMOD][EXACTF] = compare_left_tail;
6159 1           dispatch[LNBREAK][EXACTF] = compare_mismatch;
6160 1           dispatch[LOOKBEHIND_END][EXACTF] = compare_left_tail;
6161 1           dispatch[OPTIMIZED][EXACTF] = compare_left_tail;
6162              
6163 1           dispatch[SUCCEED][EXACTFU] = compare_left_tail;
6164 1           dispatch[MBOL][EXACTFU] = compare_bol;
6165 1           dispatch[SBOL][EXACTFU] = compare_bol;
6166 1           dispatch[BOUND][EXACTFU] = compare_mismatch;
6167 1           dispatch[NBOUND][EXACTFU] = compare_mismatch;
6168 1           dispatch[REG_ANY][EXACTFU] = compare_mismatch;
6169 1           dispatch[SANY][EXACTFU] = compare_mismatch;
6170 1           dispatch[ANYOF][EXACTFU] = compare_anyof_exactf;
6171 1           dispatch[ANYOFD][EXACTFU] = compare_anyof_exactf;
6172 1           dispatch[ANYOFR][EXACTFU] = compare_anyofr_exactf;
6173 1           dispatch[ANYOFM][EXACTFU] = compare_anyofm_exactf;
6174 1           dispatch[NANYOFM][EXACTFU] = compare_mismatch;
6175 1           dispatch[POSIXD][EXACTFU] = compare_mismatch;
6176 1           dispatch[POSIXU][EXACTFU] = compare_mismatch;
6177 1           dispatch[POSIXA][EXACTFU] = compare_mismatch;
6178 1           dispatch[NPOSIXD][EXACTFU] = compare_mismatch;
6179 1           dispatch[NPOSIXU][EXACTFU] = compare_mismatch;
6180 1           dispatch[NPOSIXA][EXACTFU] = compare_mismatch;
6181 1           dispatch[BRANCH][EXACTFU] = compare_left_branch;
6182 1           dispatch[EXACT][EXACTFU] = compare_exact_exactf;
6183 1           dispatch[EXACTF][EXACTFU] = compare_exactf_exactf;
6184 1           dispatch[EXACTFU][EXACTFU] = compare_exactf_exactf;
6185 1           dispatch[NOTHING][EXACTFU] = compare_left_tail;
6186 1           dispatch[STAR][EXACTFU] = compare_mismatch;
6187 1           dispatch[PLUS][EXACTFU] = compare_left_plus;
6188 1           dispatch[CURLY][EXACTFU] = compare_left_curly;
6189 1           dispatch[CURLYM][EXACTFU] = compare_left_curly;
6190 1           dispatch[CURLYX][EXACTFU] = compare_left_curly;
6191 1           dispatch[OPEN][EXACTFU] = compare_left_open;
6192 1           dispatch[CLOSE][EXACTFU] = compare_left_tail;
6193 1           dispatch[IFMATCH][EXACTFU] = compare_after_assertion;
6194 1           dispatch[UNLESSM][EXACTFU] = compare_after_assertion;
6195 1           dispatch[OPFAIL][EXACTFU] = compare_after_alt_assertion;
6196 1           dispatch[MINMOD][EXACTFU] = compare_left_tail;
6197 1           dispatch[LNBREAK][EXACTFU] = compare_mismatch;
6198 1           dispatch[LOOKBEHIND_END][EXACTFU] = compare_left_tail;
6199 1           dispatch[OPTIMIZED][EXACTFU] = compare_left_tail;
6200              
6201 1           dispatch[EXACT_REQ8][EXACT_REQ8] = compare_exact_exact;
6202              
6203 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6204             {
6205 111           dispatch[i][NOTHING] = compare_next;
6206             }
6207              
6208 1           dispatch[SUCCEED][NOTHING] = compare_tails;
6209 1           dispatch[NOTHING][NOTHING] = compare_tails;
6210 1           dispatch[TAIL][NOTHING] = compare_tails;
6211 1           dispatch[WHILEM][NOTHING] = compare_tails;
6212 1           dispatch[CLOSE][NOTHING] = compare_tails;
6213 1           dispatch[OPFAIL][NOTHING] = compare_tails;
6214 1           dispatch[MINMOD][NOTHING] = compare_tails;
6215 1           dispatch[LOOKBEHIND_END][NOTHING] = compare_tails;
6216 1           dispatch[OPTIMIZED][NOTHING] = compare_tails;
6217              
6218 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6219             {
6220 111           dispatch[i][TAIL] = compare_next;
6221             }
6222              
6223 1           dispatch[SUCCEED][TAIL] = compare_tails;
6224 1           dispatch[NOTHING][TAIL] = compare_tails;
6225 1           dispatch[TAIL][TAIL] = compare_tails;
6226 1           dispatch[WHILEM][TAIL] = compare_tails;
6227 1           dispatch[CLOSE][TAIL] = compare_tails;
6228 1           dispatch[OPFAIL][TAIL] = compare_tails;
6229 1           dispatch[MINMOD][TAIL] = compare_tails;
6230 1           dispatch[LOOKBEHIND_END][TAIL] = compare_tails;
6231 1           dispatch[OPTIMIZED][TAIL] = compare_tails;
6232              
6233 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6234             {
6235 111           dispatch[i][STAR] = compare_right_star;
6236             }
6237              
6238 1           dispatch[SUCCEED][STAR] = compare_left_tail;
6239 1           dispatch[EOS][STAR] = compare_tails;
6240 1           dispatch[EOL][STAR] = compare_tails;
6241 1           dispatch[MEOL][STAR] = compare_tails;
6242 1           dispatch[SEOL][STAR] = compare_tails;
6243 1           dispatch[NOTHING][STAR] = compare_left_tail;
6244 1           dispatch[TAIL][STAR] = compare_left_tail;
6245 1           dispatch[STAR][STAR] = compare_repeat_star;
6246 1           dispatch[PLUS][STAR] = compare_repeat_star;
6247 1           dispatch[CURLY][STAR] = compare_curly_star;
6248 1           dispatch[CURLYM][STAR] = compare_curly_star;
6249 1           dispatch[CURLYX][STAR] = compare_curly_star;
6250 1           dispatch[WHILEM][STAR] = compare_left_tail;
6251 1           dispatch[OPEN][STAR] = compare_left_open;
6252 1           dispatch[CLOSE][STAR] = compare_left_tail;
6253 1           dispatch[IFMATCH][STAR] = compare_after_assertion;
6254 1           dispatch[UNLESSM][STAR] = compare_after_assertion;
6255 1           dispatch[OPFAIL][STAR] = compare_after_alt_assertion;
6256 1           dispatch[MINMOD][STAR] = compare_left_tail;
6257 1           dispatch[LOOKBEHIND_END][STAR] = compare_left_tail;
6258 1           dispatch[OPTIMIZED][STAR] = compare_left_tail;
6259              
6260 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6261             {
6262 111           dispatch[i][PLUS] = compare_right_plus;
6263             }
6264              
6265 1           dispatch[SUCCEED][PLUS] = compare_left_tail;
6266 1           dispatch[NOTHING][PLUS] = compare_left_tail;
6267 1           dispatch[TAIL][PLUS] = compare_left_tail;
6268 1           dispatch[PLUS][PLUS] = compare_plus_plus;
6269 1           dispatch[CURLY][PLUS] = compare_curly_plus;
6270 1           dispatch[CURLYM][PLUS] = compare_curly_plus;
6271 1           dispatch[CURLYX][PLUS] = compare_curly_plus;
6272 1           dispatch[WHILEM][PLUS] = compare_left_tail;
6273 1           dispatch[OPEN][PLUS] = compare_left_open;
6274 1           dispatch[CLOSE][PLUS] = compare_left_tail;
6275 1           dispatch[IFMATCH][PLUS] = compare_after_assertion;
6276 1           dispatch[UNLESSM][PLUS] = compare_after_assertion;
6277 1           dispatch[OPFAIL][PLUS] = compare_after_alt_assertion;
6278 1           dispatch[MINMOD][PLUS] = compare_left_tail;
6279 1           dispatch[LOOKBEHIND_END][PLUS] = compare_left_tail;
6280 1           dispatch[OPTIMIZED][PLUS] = compare_left_tail;
6281              
6282 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6283             {
6284 111           dispatch[i][CURLY] = compare_right_curly;
6285             }
6286              
6287 1           dispatch[SUCCEED][CURLY] = compare_left_tail;
6288 1           dispatch[NOTHING][CURLY] = compare_left_tail;
6289 1           dispatch[TAIL][CURLY] = compare_left_tail;
6290 1           dispatch[PLUS][CURLY] = compare_plus_curly;
6291 1           dispatch[CURLY][CURLY] = compare_curly_curly;
6292 1           dispatch[CURLYM][CURLY] = compare_curly_curly;
6293 1           dispatch[CURLYX][CURLY] = compare_curly_curly;
6294 1           dispatch[WHILEM][CURLY] = compare_left_tail;
6295 1           dispatch[OPEN][CURLY] = compare_left_open;
6296 1           dispatch[CLOSE][CURLY] = compare_left_tail;
6297 1           dispatch[IFMATCH][CURLY] = compare_after_assertion;
6298 1           dispatch[UNLESSM][CURLY] = compare_after_assertion;
6299 1           dispatch[SUSPEND][CURLY] = compare_suspend_curly;
6300 1           dispatch[OPFAIL][CURLY] = compare_after_alt_assertion;
6301 1           dispatch[MINMOD][CURLY] = compare_left_tail;
6302 1           dispatch[LOOKBEHIND_END][CURLY] = compare_left_tail;
6303 1           dispatch[OPTIMIZED][CURLY] = compare_left_tail;
6304              
6305 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6306             {
6307 111           dispatch[i][CURLYM] = compare_right_curly;
6308             }
6309              
6310 1           dispatch[SUCCEED][CURLYM] = compare_left_tail;
6311 1           dispatch[NOTHING][CURLYM] = compare_left_tail;
6312 1           dispatch[TAIL][CURLYM] = compare_left_tail;
6313 1           dispatch[PLUS][CURLYM] = compare_plus_curly;
6314 1           dispatch[CURLY][CURLYM] = compare_curly_curly;
6315 1           dispatch[CURLYM][CURLYM] = compare_curly_curly;
6316 1           dispatch[CURLYX][CURLYM] = compare_curly_curly;
6317 1           dispatch[WHILEM][CURLYM] = compare_left_tail;
6318 1           dispatch[OPEN][CURLYM] = compare_left_open;
6319 1           dispatch[CLOSE][CURLYM] = compare_left_tail;
6320 1           dispatch[IFMATCH][CURLYM] = compare_after_assertion;
6321 1           dispatch[UNLESSM][CURLYM] = compare_after_assertion;
6322 1           dispatch[SUSPEND][CURLYM] = compare_suspend_curly;
6323 1           dispatch[OPFAIL][CURLYM] = compare_after_alt_assertion;
6324 1           dispatch[MINMOD][CURLYM] = compare_left_tail;
6325 1           dispatch[LOOKBEHIND_END][CURLYM] = compare_left_tail;
6326 1           dispatch[OPTIMIZED][CURLYM] = compare_left_tail;
6327              
6328 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6329             {
6330 111           dispatch[i][CURLYX] = compare_right_curly;
6331             }
6332              
6333 1           dispatch[SUCCEED][CURLYX] = compare_left_tail;
6334 1           dispatch[NOTHING][CURLYX] = compare_left_tail;
6335 1           dispatch[TAIL][CURLYX] = compare_left_tail;
6336 1           dispatch[PLUS][CURLYX] = compare_plus_curly;
6337 1           dispatch[CURLY][CURLYX] = compare_curly_curly;
6338 1           dispatch[CURLYM][CURLYX] = compare_curly_curly;
6339 1           dispatch[CURLYX][CURLYX] = compare_curly_curly;
6340 1           dispatch[WHILEM][CURLYX] = compare_left_tail;
6341 1           dispatch[OPEN][CURLYX] = compare_left_open;
6342 1           dispatch[CLOSE][CURLYX] = compare_left_tail;
6343 1           dispatch[IFMATCH][CURLYX] = compare_after_assertion;
6344 1           dispatch[UNLESSM][CURLYX] = compare_after_assertion;
6345 1           dispatch[SUSPEND][CURLYX] = compare_suspend_curly;
6346 1           dispatch[OPFAIL][CURLYX] = compare_after_alt_assertion;
6347 1           dispatch[MINMOD][CURLYX] = compare_left_tail;
6348 1           dispatch[LOOKBEHIND_END][CURLYX] = compare_left_tail;
6349 1           dispatch[OPTIMIZED][CURLYX] = compare_left_tail;
6350              
6351 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6352             {
6353 111           dispatch[i][WHILEM] = compare_next;
6354             }
6355              
6356 1           dispatch[SUCCEED][WHILEM] = compare_tails;
6357 1           dispatch[NOTHING][WHILEM] = compare_tails;
6358 1           dispatch[TAIL][WHILEM] = compare_tails;
6359 1           dispatch[WHILEM][WHILEM] = compare_tails;
6360 1           dispatch[CLOSE][WHILEM] = compare_tails;
6361 1           dispatch[OPFAIL][WHILEM] = compare_tails;
6362 1           dispatch[MINMOD][WHILEM] = compare_tails;
6363 1           dispatch[LOOKBEHIND_END][WHILEM] = compare_tails;
6364 1           dispatch[OPTIMIZED][WHILEM] = compare_tails;
6365              
6366 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6367             {
6368 111           dispatch[i][OPEN] = compare_right_open;
6369             }
6370              
6371 1           dispatch[OPEN][OPEN] = compare_open_open;
6372              
6373 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6374             {
6375 111           dispatch[i][CLOSE] = compare_next;
6376             }
6377              
6378 1           dispatch[SUCCEED][CLOSE] = compare_tails;
6379 1           dispatch[NOTHING][CLOSE] = compare_tails;
6380 1           dispatch[TAIL][CLOSE] = compare_tails;
6381 1           dispatch[WHILEM][CLOSE] = compare_tails;
6382 1           dispatch[CLOSE][CLOSE] = compare_tails;
6383 1           dispatch[OPFAIL][CLOSE] = compare_tails;
6384 1           dispatch[MINMOD][CLOSE] = compare_tails;
6385 1           dispatch[LOOKBEHIND_END][CLOSE] = compare_tails;
6386 1           dispatch[OPTIMIZED][CLOSE] = compare_tails;
6387              
6388 1           dispatch[SUCCEED][IFMATCH] = compare_left_tail;
6389 1           dispatch[MBOL][IFMATCH] = compare_bol;
6390 1           dispatch[SBOL][IFMATCH] = compare_bol;
6391 1           dispatch[BOUND][IFMATCH] = compare_mismatch;
6392 1           dispatch[NBOUND][IFMATCH] = compare_mismatch;
6393 1           dispatch[REG_ANY][IFMATCH] = compare_mismatch;
6394 1           dispatch[SANY][IFMATCH] = compare_mismatch;
6395 1           dispatch[ANYOF][IFMATCH] = compare_mismatch;
6396 1           dispatch[ANYOFD][IFMATCH] = compare_mismatch;
6397 1           dispatch[ANYOFR][IFMATCH] = compare_mismatch;
6398 1           dispatch[ANYOFM][IFMATCH] = compare_mismatch;
6399 1           dispatch[NANYOFM][IFMATCH] = compare_mismatch;
6400 1           dispatch[POSIXD][IFMATCH] = compare_mismatch;
6401 1           dispatch[POSIXU][IFMATCH] = compare_mismatch;
6402 1           dispatch[POSIXA][IFMATCH] = compare_mismatch;
6403 1           dispatch[NPOSIXD][IFMATCH] = compare_mismatch;
6404 1           dispatch[NPOSIXU][IFMATCH] = compare_mismatch;
6405 1           dispatch[NPOSIXA][IFMATCH] = compare_mismatch;
6406 1           dispatch[BRANCH][IFMATCH] = compare_mismatch;
6407 1           dispatch[EXACT][IFMATCH] = compare_mismatch;
6408 1           dispatch[EXACTF][IFMATCH] = compare_mismatch;
6409 1           dispatch[EXACTFU][IFMATCH] = compare_mismatch;
6410 1           dispatch[NOTHING][IFMATCH] = compare_left_tail;
6411 1           dispatch[TAIL][IFMATCH] = compare_left_tail;
6412 1           dispatch[STAR][IFMATCH] = compare_mismatch;
6413 1           dispatch[PLUS][IFMATCH] = compare_mismatch;
6414 1           dispatch[CURLY][IFMATCH] = compare_mismatch;
6415 1           dispatch[CURLYM][IFMATCH] = compare_mismatch;
6416 1           dispatch[CURLYX][IFMATCH] = compare_mismatch;
6417 1           dispatch[WHILEM][IFMATCH] = compare_left_tail;
6418 1           dispatch[OPEN][IFMATCH] = compare_left_open;
6419 1           dispatch[CLOSE][IFMATCH] = compare_left_tail;
6420 1           dispatch[IFMATCH][IFMATCH] = compare_positive_assertions;
6421 1           dispatch[UNLESSM][IFMATCH] = compare_mismatch;
6422 1           dispatch[OPFAIL][IFMATCH] = compare_mismatch;
6423 1           dispatch[MINMOD][IFMATCH] = compare_left_tail;
6424 1           dispatch[LNBREAK][IFMATCH] = compare_mismatch;
6425 1           dispatch[LOOKBEHIND_END][IFMATCH] = compare_left_tail;
6426 1           dispatch[OPTIMIZED][IFMATCH] = compare_left_tail;
6427              
6428 1           dispatch[SUCCEED][UNLESSM] = compare_left_tail;
6429 1           dispatch[MBOL][UNLESSM] = compare_bol;
6430 1           dispatch[SBOL][UNLESSM] = compare_bol;
6431 1           dispatch[BOUND][UNLESSM] = compare_mismatch;
6432 1           dispatch[NBOUND][UNLESSM] = compare_mismatch;
6433 1           dispatch[REG_ANY][UNLESSM] = compare_mismatch;
6434 1           dispatch[SANY][UNLESSM] = compare_mismatch;
6435 1           dispatch[ANYOF][UNLESSM] = compare_mismatch;
6436 1           dispatch[ANYOFD][UNLESSM] = compare_mismatch;
6437 1           dispatch[ANYOFR][UNLESSM] = compare_mismatch;
6438 1           dispatch[ANYOFM][UNLESSM] = compare_mismatch;
6439 1           dispatch[NANYOFM][UNLESSM] = compare_mismatch;
6440 1           dispatch[POSIXD][UNLESSM] = compare_mismatch;
6441 1           dispatch[POSIXU][UNLESSM] = compare_mismatch;
6442 1           dispatch[POSIXA][UNLESSM] = compare_mismatch;
6443 1           dispatch[NPOSIXD][UNLESSM] = compare_mismatch;
6444 1           dispatch[NPOSIXU][UNLESSM] = compare_mismatch;
6445 1           dispatch[NPOSIXA][UNLESSM] = compare_mismatch;
6446 1           dispatch[BRANCH][UNLESSM] = compare_mismatch;
6447 1           dispatch[EXACT][UNLESSM] = compare_mismatch;
6448 1           dispatch[EXACTF][UNLESSM] = compare_mismatch;
6449 1           dispatch[EXACTFU][UNLESSM] = compare_mismatch;
6450 1           dispatch[NOTHING][UNLESSM] = compare_left_tail;
6451 1           dispatch[TAIL][UNLESSM] = compare_left_tail;
6452 1           dispatch[STAR][UNLESSM] = compare_mismatch;
6453 1           dispatch[PLUS][UNLESSM] = compare_mismatch;
6454 1           dispatch[CURLY][UNLESSM] = compare_mismatch;
6455 1           dispatch[CURLYM][UNLESSM] = compare_mismatch;
6456 1           dispatch[CURLYX][UNLESSM] = compare_mismatch;
6457 1           dispatch[WHILEM][UNLESSM] = compare_left_tail;
6458 1           dispatch[OPEN][UNLESSM] = compare_left_open;
6459 1           dispatch[CLOSE][UNLESSM] = compare_left_tail;
6460 1           dispatch[IFMATCH][UNLESSM] = compare_mismatch;
6461 1           dispatch[UNLESSM][UNLESSM] = compare_negative_assertions;
6462 1           dispatch[OPFAIL][UNLESSM] = compare_mismatch;
6463 1           dispatch[MINMOD][UNLESSM] = compare_left_tail;
6464 1           dispatch[LNBREAK][UNLESSM] = compare_mismatch;
6465 1           dispatch[LOOKBEHIND_END][UNLESSM] = compare_left_tail;
6466 1           dispatch[OPTIMIZED][UNLESSM] = compare_left_tail;
6467              
6468 1           dispatch[SUCCEED][OPFAIL] = compare_left_tail;
6469 1           dispatch[MBOL][OPFAIL] = compare_bol;
6470 1           dispatch[SBOL][OPFAIL] = compare_bol;
6471 1           dispatch[BOUND][OPFAIL] = compare_mismatch;
6472 1           dispatch[NBOUND][OPFAIL] = compare_mismatch;
6473 1           dispatch[REG_ANY][OPFAIL] = compare_mismatch;
6474 1           dispatch[SANY][OPFAIL] = compare_mismatch;
6475 1           dispatch[ANYOF][OPFAIL] = compare_mismatch;
6476 1           dispatch[ANYOFD][OPFAIL] = compare_mismatch;
6477 1           dispatch[ANYOFR][OPFAIL] = compare_mismatch;
6478 1           dispatch[ANYOFM][OPFAIL] = compare_mismatch;
6479 1           dispatch[NANYOFM][OPFAIL] = compare_mismatch;
6480 1           dispatch[POSIXD][OPFAIL] = compare_mismatch;
6481 1           dispatch[POSIXU][OPFAIL] = compare_mismatch;
6482 1           dispatch[POSIXA][OPFAIL] = compare_mismatch;
6483 1           dispatch[NPOSIXD][OPFAIL] = compare_mismatch;
6484 1           dispatch[NPOSIXU][OPFAIL] = compare_mismatch;
6485 1           dispatch[NPOSIXA][OPFAIL] = compare_mismatch;
6486 1           dispatch[BRANCH][OPFAIL] = compare_mismatch;
6487 1           dispatch[EXACT][OPFAIL] = compare_mismatch;
6488 1           dispatch[EXACTF][OPFAIL] = compare_mismatch;
6489 1           dispatch[EXACTFU][OPFAIL] = compare_mismatch;
6490 1           dispatch[NOTHING][OPFAIL] = compare_left_tail;
6491 1           dispatch[TAIL][OPFAIL] = compare_left_tail;
6492 1           dispatch[STAR][OPFAIL] = compare_mismatch;
6493 1           dispatch[PLUS][OPFAIL] = compare_mismatch;
6494 1           dispatch[CURLY][OPFAIL] = compare_mismatch;
6495 1           dispatch[CURLYM][OPFAIL] = compare_mismatch;
6496 1           dispatch[CURLYX][OPFAIL] = compare_mismatch;
6497 1           dispatch[WHILEM][OPFAIL] = compare_left_tail;
6498 1           dispatch[OPEN][OPFAIL] = compare_left_open;
6499 1           dispatch[CLOSE][OPFAIL] = compare_left_tail;
6500 1           dispatch[IFMATCH][OPFAIL] = compare_mismatch;
6501 1           dispatch[UNLESSM][OPFAIL] = compare_mismatch;
6502 1           dispatch[OPFAIL][OPFAIL] = compare_negative_alt_assertions;
6503 1           dispatch[MINMOD][OPFAIL] = compare_left_tail;
6504 1           dispatch[LNBREAK][OPFAIL] = compare_mismatch;
6505 1           dispatch[LOOKBEHIND_END][OPFAIL] = compare_left_tail;
6506 1           dispatch[OPTIMIZED][OPFAIL] = compare_left_tail;
6507              
6508 1           dispatch[SUSPEND][SUSPEND] = compare_subexpressions;
6509              
6510 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6511             {
6512 111           dispatch[i][MINMOD] = compare_next;
6513             }
6514              
6515 1           dispatch[SUCCEED][MINMOD] = compare_tails;
6516 1           dispatch[NOTHING][MINMOD] = compare_tails;
6517 1           dispatch[TAIL][MINMOD] = compare_tails;
6518 1           dispatch[WHILEM][MINMOD] = compare_tails;
6519 1           dispatch[CLOSE][MINMOD] = compare_tails;
6520 1           dispatch[MINMOD][MINMOD] = compare_tails;
6521 1           dispatch[LOOKBEHIND_END][MINMOD] = compare_tails;
6522 1           dispatch[OPTIMIZED][MINMOD] = compare_tails;
6523              
6524 1           dispatch[SUCCEED][LNBREAK] = compare_left_tail;
6525 1           dispatch[SBOL][LNBREAK] = compare_bol;
6526 1           dispatch[MBOL][LNBREAK] = compare_bol;
6527 1           dispatch[BOUND][LNBREAK] = compare_mismatch;
6528 1           dispatch[NBOUND][LNBREAK] = compare_mismatch;
6529 1           dispatch[REG_ANY][LNBREAK] = compare_mismatch;
6530 1           dispatch[SANY][LNBREAK] = compare_mismatch;
6531 1           dispatch[ANYOF][LNBREAK] = compare_anyof_lnbreak;
6532 1           dispatch[ANYOFD][LNBREAK] = compare_anyof_lnbreak;
6533 1           dispatch[ANYOFR][LNBREAK] = compare_mismatch;
6534 1           dispatch[ANYOFM][LNBREAK] = compare_mismatch;
6535 1           dispatch[NANYOFM][LNBREAK] = compare_mismatch;
6536 1           dispatch[POSIXD][LNBREAK] = compare_posix_lnbreak;
6537 1           dispatch[POSIXU][LNBREAK] = compare_posix_lnbreak;
6538 1           dispatch[POSIXA][LNBREAK] = compare_posix_lnbreak;
6539 1           dispatch[NPOSIXD][LNBREAK] = compare_mismatch;
6540 1           dispatch[NPOSIXU][LNBREAK] = compare_mismatch;
6541 1           dispatch[NPOSIXA][LNBREAK] = compare_mismatch;
6542 1           dispatch[BRANCH][LNBREAK] = compare_left_branch;
6543 1           dispatch[EXACT][LNBREAK] = compare_exact_lnbreak;
6544 1           dispatch[EXACTFU][LNBREAK] = compare_exact_lnbreak;
6545 1           dispatch[NOTHING][LNBREAK] = compare_left_tail;
6546 1           dispatch[TAIL][LNBREAK] = compare_left_tail;
6547 1           dispatch[STAR][LNBREAK] = compare_mismatch;
6548 1           dispatch[PLUS][LNBREAK] = compare_left_plus;
6549 1           dispatch[CURLY][LNBREAK] = compare_left_curly;
6550 1           dispatch[CURLYM][LNBREAK] = compare_left_curly;
6551 1           dispatch[CURLYX][LNBREAK] = compare_left_curly;
6552 1           dispatch[WHILEM][LNBREAK] = compare_left_tail;
6553 1           dispatch[OPEN][LNBREAK] = compare_left_open;
6554 1           dispatch[CLOSE][LNBREAK] = compare_left_tail;
6555 1           dispatch[IFMATCH][LNBREAK] = compare_after_assertion;
6556 1           dispatch[UNLESSM][LNBREAK] = compare_after_assertion;
6557 1           dispatch[OPFAIL][LNBREAK] = compare_after_alt_assertion;
6558 1           dispatch[MINMOD][LNBREAK] = compare_left_tail;
6559 1           dispatch[LOOKBEHIND_END][LNBREAK] = compare_left_tail;
6560 1           dispatch[LNBREAK][LNBREAK] = compare_tails;
6561              
6562 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6563             {
6564 111           dispatch[i][LOOKBEHIND_END] = compare_next;
6565             }
6566              
6567 1           dispatch[SUCCEED][LOOKBEHIND_END] = compare_tails;
6568 1           dispatch[NOTHING][LOOKBEHIND_END] = compare_tails;
6569 1           dispatch[TAIL][LOOKBEHIND_END] = compare_tails;
6570 1           dispatch[WHILEM][LOOKBEHIND_END] = compare_tails;
6571 1           dispatch[CLOSE][LOOKBEHIND_END] = compare_tails;
6572 1           dispatch[MINMOD][LOOKBEHIND_END] = compare_tails;
6573 1           dispatch[LOOKBEHIND_END][LOOKBEHIND_END] = compare_tails;
6574 1           dispatch[OPTIMIZED][LOOKBEHIND_END] = compare_tails;
6575              
6576 112 100         for (i = 0; i < REGNODE_MAX; ++i)
6577             {
6578 111           dispatch[i][OPTIMIZED] = compare_next;
6579             }
6580              
6581 1           dispatch[SUCCEED][OPTIMIZED] = compare_tails;
6582 1           dispatch[NOTHING][OPTIMIZED] = compare_tails;
6583 1           dispatch[TAIL][OPTIMIZED] = compare_tails;
6584 1           dispatch[WHILEM][OPTIMIZED] = compare_tails;
6585 1           dispatch[CLOSE][OPTIMIZED] = compare_tails;
6586 1           dispatch[MINMOD][OPTIMIZED] = compare_tails;
6587 1           dispatch[LOOKBEHIND_END][OPTIMIZED] = compare_tails;
6588 1           dispatch[OPTIMIZED][OPTIMIZED] = compare_tails;
6589 1           }