be9fdfae158a863cae240f399ed3dd11b074d43a
[haskell-directory.git] / cbits / regex / regcomp.c
1 /*-
2  * Copyright (c) 1992, 1993, 1994 Henry Spencer.
3  * Copyright (c) 1992, 1993, 1994
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Henry Spencer.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by the University of
20  *      California, Berkeley and its contributors.
21  * 4. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *      @(#)regcomp.c   8.5 (Berkeley) 3/20/94
38  *
39  * $FreeBSD: src/lib/libc/regex/regcomp.c,v 1.13.2.1 2000/07/31 06:30:37 dcs Exp $
40  */
41
42 #if defined(LIBC_SCCS) && !defined(lint)
43 static char sccsid[] = "@(#)regcomp.c   8.5 (Berkeley) 3/20/94";
44 #endif /* LIBC_SCCS and not lint */
45
46 #include <sys/types.h>
47 #include <stdio.h>
48 #include <string.h>
49 #include <ctype.h>
50 #include <limits.h>
51 #include <stdlib.h>
52 #include "regex/regex.h"
53
54 // removed collate stuff --SDM
55 // #include "collate.h"
56
57 #ifdef _WIN32
58 #define isblank(c) ((c) == ' ' || (c) == '\t')
59 #endif
60
61 #include "utils.h"
62 #include "regex2.h"
63
64 #include "cclass.h"
65 #include "cname.h"
66
67 /*
68  * parse structure, passed up and down to avoid global variables and
69  * other clumsinesses
70  */
71 struct parse {
72         char *next;             /* next character in RE */
73         char *end;              /* end of string (-> NUL normally) */
74         int error;              /* has an error been seen? */
75         sop *strip;             /* malloced strip */
76         sopno ssize;            /* malloced strip size (allocated) */
77         sopno slen;             /* malloced strip length (used) */
78         int ncsalloc;           /* number of csets allocated */
79         struct re_guts *g;
80 #       define  NPAREN  10      /* we need to remember () 1-9 for back refs */
81         sopno pbegin[NPAREN];   /* -> ( ([0] unused) */
82         sopno pend[NPAREN];     /* -> ) ([0] unused) */
83 };
84
85 /* ========= begin header generated by ./mkh ========= */
86 #ifdef __cplusplus
87 extern "C" {
88 #endif
89
90 /* === regcomp.c === */
91 static void p_ere (struct parse *p, int stop);
92 static void p_ere_exp (struct parse *p);
93 static void p_str (struct parse *p);
94 static void p_bre (struct parse *p, int end1, int end2);
95 static int p_simp_re (struct parse *p, int starordinary);
96 static int p_count (struct parse *p);
97 static void p_bracket (struct parse *p);
98 static void p_b_term (struct parse *p, cset *cs);
99 static void p_b_cclass (struct parse *p, cset *cs);
100 static void p_b_eclass (struct parse *p, cset *cs);
101 static char p_b_symbol (struct parse *p);
102 static char p_b_coll_elem (struct parse *p, int endc);
103 static char othercase (int ch);
104 static void bothcases (struct parse *p, int ch);
105 static void ordinary (struct parse *p, int ch);
106 static void nonnewline (struct parse *p);
107 static void repeat (struct parse *p, sopno start, int from, int to);
108 static int seterr (struct parse *p, int e);
109 static cset *allocset (struct parse *p);
110 static void freeset (struct parse *p, cset *cs);
111 static int freezeset (struct parse *p, cset *cs);
112 static int firstch (struct parse *p, cset *cs);
113 static int nch (struct parse *p, cset *cs);
114 static void mcadd (struct parse *p, cset *cs, char *cp);
115 #if used
116 static void mcsub (cset *cs, char *cp);
117 static int mcin (cset *cs, char *cp);
118 static char *mcfind (cset *cs, char *cp);
119 #endif
120 static void mcinvert (struct parse *p, cset *cs);
121 static void mccase (struct parse *p, cset *cs);
122 static int isinsets (struct re_guts *g, int c);
123 static int samesets (struct re_guts *g, int c1, int c2);
124 static void categorize (struct parse *p, struct re_guts *g);
125 static sopno dupl (struct parse *p, sopno start, sopno finish);
126 static void doemit (struct parse *p, sop op, size_t opnd);
127 static void doinsert (struct parse *p, sop op, size_t opnd, sopno pos);
128 static void dofwd (struct parse *p, sopno pos, sop value);
129 static void enlarge (struct parse *p, sopno size);
130 static void stripsnug (struct parse *p, struct re_guts *g);
131 static void findmust (struct parse *p, struct re_guts *g);
132 static int altoffset (sop *scan, int offset, int mccs);
133 static void computejumps (struct parse *p, struct re_guts *g);
134 static void computematchjumps (struct parse *p, struct re_guts *g);
135 static sopno pluscount (struct parse *p, struct re_guts *g);
136
137 #ifdef __cplusplus
138 }
139 #endif
140 /* ========= end header generated by ./mkh ========= */
141
142 static char nuls[10];           /* place to point scanner in event of error */
143
144 /*
145  * macros for use with parse structure
146  * BEWARE:  these know that the parse structure is named `p' !!!
147  */
148 #define PEEK()  (*p->next)
149 #define PEEK2() (*(p->next+1))
150 #define MORE()  (p->next < p->end)
151 #define MORE2() (p->next+1 < p->end)
152 #define SEE(c)  (MORE() && PEEK() == (c))
153 #define SEETWO(a, b)    (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
154 #define EAT(c)  ((SEE(c)) ? (NEXT(), 1) : 0)
155 #define EATTWO(a, b)    ((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
156 #define NEXT()  (p->next++)
157 #define NEXT2() (p->next += 2)
158 #define NEXTn(n)        (p->next += (n))
159 #define GETNEXT()       (*p->next++)
160 #define SETERROR(e)     seterr(p, (e))
161 #define REQUIRE(co, e)  ((co) || SETERROR(e))
162 #define MUSTSEE(c, e)   (REQUIRE(MORE() && PEEK() == (c), e))
163 #define MUSTEAT(c, e)   (REQUIRE(MORE() && GETNEXT() == (c), e))
164 #define MUSTNOTSEE(c, e)        (REQUIRE(!MORE() || PEEK() != (c), e))
165 #define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd))
166 #define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
167 #define AHEAD(pos)              dofwd(p, pos, HERE()-(pos))
168 #define ASTERN(sop, pos)        EMIT(sop, HERE()-pos)
169 #define HERE()          (p->slen)
170 #define THERE()         (p->slen - 1)
171 #define THERETHERE()    (p->slen - 2)
172 #define DROP(n) (p->slen -= (n))
173
174 #ifndef NDEBUG
175 static int never = 0;           /* for use in asserts; shuts lint up */
176 #else
177 #define never   0               /* some <assert.h>s have bugs too */
178 #endif
179
180 /* Macro used by computejump()/computematchjump() */
181 #define MIN(a,b)        ((a)<(b)?(a):(b))
182
183 /*
184  - regcomp - interface for parser and compilation
185  = extern int regcomp(regex_t *, const char *, int);
186  = #define      REG_BASIC       0000
187  = #define      REG_EXTENDED    0001
188  = #define      REG_ICASE       0002
189  = #define      REG_NOSUB       0004
190  = #define      REG_NEWLINE     0010
191  = #define      REG_NOSPEC      0020
192  = #define      REG_PEND        0040
193  = #define      REG_DUMP        0200
194  */
195 int                             /* 0 success, otherwise REG_something */
196 regcomp(preg, pattern, cflags)
197 regex_t *preg;
198 const char *pattern;
199 int cflags;
200 {
201         struct parse pa;
202         register struct re_guts *g;
203         register struct parse *p = &pa;
204         register int i;
205         register size_t len;
206 #ifdef REDEBUG
207 #       define  GOODFLAGS(f)    (f)
208 #else
209 #       define  GOODFLAGS(f)    ((f)&~REG_DUMP)
210 #endif
211
212         cflags = GOODFLAGS(cflags);
213         if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
214                 return(REG_INVARG);
215
216         if (cflags&REG_PEND) {
217                 if (preg->re_endp < pattern)
218                         return(REG_INVARG);
219                 len = preg->re_endp - pattern;
220         } else
221                 len = strlen((char *)pattern);
222
223         /* do the mallocs early so failure handling is easy */
224         g = (struct re_guts *)malloc(sizeof(struct re_guts) +
225                                                         (NC-1)*sizeof(cat_t));
226         if (g == NULL)
227                 return(REG_ESPACE);
228         p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */
229         p->strip = (sop *)malloc(p->ssize * sizeof(sop));
230         p->slen = 0;
231         if (p->strip == NULL) {
232                 free((char *)g);
233                 return(REG_ESPACE);
234         }
235
236         /* set things up */
237         p->g = g;
238         p->next = (char *)pattern;      /* convenience; we do not modify it */
239         p->end = p->next + len;
240         p->error = 0;
241         p->ncsalloc = 0;
242         for (i = 0; i < NPAREN; i++) {
243                 p->pbegin[i] = 0;
244                 p->pend[i] = 0;
245         }
246         g->csetsize = NC;
247         g->sets = NULL;
248         g->setbits = NULL;
249         g->ncsets = 0;
250         g->cflags = cflags;
251         g->iflags = 0;
252         g->nbol = 0;
253         g->neol = 0;
254         g->must = NULL;
255         g->moffset = -1;
256         g->charjump = NULL;
257         g->matchjump = NULL;
258         g->mlen = 0;
259         g->nsub = 0;
260         g->ncategories = 1;     /* category 0 is "everything else" */
261         g->categories = &g->catspace[-(CHAR_MIN)];
262         (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t));
263         g->backrefs = 0;
264
265         /* do it */
266         EMIT(OEND, 0);
267         g->firststate = THERE();
268         if (cflags&REG_EXTENDED)
269                 p_ere(p, OUT);
270         else if (cflags&REG_NOSPEC)
271                 p_str(p);
272         else
273                 p_bre(p, OUT, OUT);
274         EMIT(OEND, 0);
275         g->laststate = THERE();
276
277         /* tidy up loose ends and fill things in */
278         categorize(p, g);
279         stripsnug(p, g);
280         findmust(p, g);
281         /* only use Boyer-Moore algorithm if the pattern is bigger
282          * than three characters
283          */
284         if(g->mlen > 3) {
285                 computejumps(p, g);
286                 computematchjumps(p, g);
287                 if(g->matchjump == NULL && g->charjump != NULL) {
288                         free(g->charjump);
289                         g->charjump = NULL;
290                 }
291         }
292         g->nplus = pluscount(p, g);
293         g->magic = MAGIC2;
294         preg->re_nsub = g->nsub;
295         preg->re_g = g;
296         preg->re_magic = MAGIC1;
297 #ifndef REDEBUG
298         /* not debugging, so can't rely on the assert() in regexec() */
299         if (g->iflags&BAD)
300                 SETERROR(REG_ASSERT);
301 #endif
302
303         /* win or lose, we're done */
304         if (p->error != 0)      /* lose */
305                 regfree(preg);
306         return(p->error);
307 }
308
309 /*
310  - p_ere - ERE parser top level, concatenation and alternation
311  == static void p_ere(register struct parse *p, int stop);
312  */
313 static void
314 p_ere(p, stop)
315 register struct parse *p;
316 int stop;                       /* character this ERE should end at */
317 {
318         register char c;
319         register sopno prevback;
320         register sopno prevfwd;
321         register sopno conc;
322         register int first = 1;         /* is this the first alternative? */
323
324         for (;;) {
325                 /* do a bunch of concatenated expressions */
326                 conc = HERE();
327                 while (MORE() && (c = PEEK()) != '|' && c != stop)
328                         p_ere_exp(p);
329                 (void)REQUIRE(HERE() != conc, REG_EMPTY);       /* require nonempty */
330
331                 if (!EAT('|'))
332                         break;          /* NOTE BREAK OUT */
333
334                 if (first) {
335                         INSERT(OCH_, conc);     /* offset is wrong */
336                         prevfwd = conc;
337                         prevback = conc;
338                         first = 0;
339                 }
340                 ASTERN(OOR1, prevback);
341                 prevback = THERE();
342                 AHEAD(prevfwd);                 /* fix previous offset */
343                 prevfwd = HERE();
344                 EMIT(OOR2, 0);                  /* offset is very wrong */
345         }
346
347         if (!first) {           /* tail-end fixups */
348                 AHEAD(prevfwd);
349                 ASTERN(O_CH, prevback);
350         }
351
352         assert(!MORE() || SEE(stop));
353 }
354
355 /*
356  - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op
357  == static void p_ere_exp(register struct parse *p);
358  */
359 static void
360 p_ere_exp(p)
361 register struct parse *p;
362 {
363         register char c;
364         register sopno pos;
365         register int count;
366         register int count2;
367         register sopno subno;
368         int wascaret = 0;
369
370         assert(MORE());         /* caller should have ensured this */
371         c = GETNEXT();
372
373         pos = HERE();
374         switch (c) {
375         case '(':
376                 (void)REQUIRE(MORE(), REG_EPAREN);
377                 p->g->nsub++;
378                 subno = p->g->nsub;
379                 if (subno < NPAREN)
380                         p->pbegin[subno] = HERE();
381                 EMIT(OLPAREN, subno);
382                 if (!SEE(')'))
383                         p_ere(p, ')');
384                 if (subno < NPAREN) {
385                         p->pend[subno] = HERE();
386                         assert(p->pend[subno] != 0);
387                 }
388                 EMIT(ORPAREN, subno);
389                 (void)MUSTEAT(')', REG_EPAREN);
390                 break;
391 #ifndef POSIX_MISTAKE
392         case ')':               /* happens only if no current unmatched ( */
393                 /*
394                  * You may ask, why the ifndef?  Because I didn't notice
395                  * this until slightly too late for 1003.2, and none of the
396                  * other 1003.2 regular-expression reviewers noticed it at
397                  * all.  So an unmatched ) is legal POSIX, at least until
398                  * we can get it fixed.
399                  */
400                 SETERROR(REG_EPAREN);
401                 break;
402 #endif
403         case '^':
404                 EMIT(OBOL, 0);
405                 p->g->iflags |= USEBOL;
406                 p->g->nbol++;
407                 wascaret = 1;
408                 break;
409         case '$':
410                 EMIT(OEOL, 0);
411                 p->g->iflags |= USEEOL;
412                 p->g->neol++;
413                 break;
414         case '|':
415                 SETERROR(REG_EMPTY);
416                 break;
417         case '*':
418         case '+':
419         case '?':
420                 SETERROR(REG_BADRPT);
421                 break;
422         case '.':
423                 if (p->g->cflags&REG_NEWLINE)
424                         nonnewline(p);
425                 else
426                         EMIT(OANY, 0);
427                 break;
428         case '[':
429                 p_bracket(p);
430                 break;
431         case '\\':
432                 (void)REQUIRE(MORE(), REG_EESCAPE);
433                 c = GETNEXT();
434                 ordinary(p, c);
435                 break;
436         case '{':               /* okay as ordinary except if digit follows */
437                 (void)REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT);
438                 /* FALLTHROUGH */
439         default:
440                 ordinary(p, c);
441                 break;
442         }
443
444         if (!MORE())
445                 return;
446         c = PEEK();
447         /* we call { a repetition if followed by a digit */
448         if (!( c == '*' || c == '+' || c == '?' ||
449                                 (c == '{' && MORE2() && isdigit((uch)PEEK2())) ))
450                 return;         /* no repetition, we're done */
451         NEXT();
452
453         (void)REQUIRE(!wascaret, REG_BADRPT);
454         switch (c) {
455         case '*':       /* implemented as +? */
456                 /* this case does not require the (y|) trick, noKLUDGE */
457                 INSERT(OPLUS_, pos);
458                 ASTERN(O_PLUS, pos);
459                 INSERT(OQUEST_, pos);
460                 ASTERN(O_QUEST, pos);
461                 break;
462         case '+':
463                 INSERT(OPLUS_, pos);
464                 ASTERN(O_PLUS, pos);
465                 break;
466         case '?':
467                 /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
468                 INSERT(OCH_, pos);              /* offset slightly wrong */
469                 ASTERN(OOR1, pos);              /* this one's right */
470                 AHEAD(pos);                     /* fix the OCH_ */
471                 EMIT(OOR2, 0);                  /* offset very wrong... */
472                 AHEAD(THERE());                 /* ...so fix it */
473                 ASTERN(O_CH, THERETHERE());
474                 break;
475         case '{':
476                 count = p_count(p);
477                 if (EAT(',')) {
478                         if (isdigit((uch)PEEK())) {
479                                 count2 = p_count(p);
480                                 (void)REQUIRE(count <= count2, REG_BADBR);
481                         } else          /* single number with comma */
482                                 count2 = INFINITY;
483                 } else          /* just a single number */
484                         count2 = count;
485                 repeat(p, pos, count, count2);
486                 if (!EAT('}')) {        /* error heuristics */
487                         while (MORE() && PEEK() != '}')
488                                 NEXT();
489                         (void)REQUIRE(MORE(), REG_EBRACE);
490                         SETERROR(REG_BADBR);
491                 }
492                 break;
493         }
494
495         if (!MORE())
496                 return;
497         c = PEEK();
498         if (!( c == '*' || c == '+' || c == '?' ||
499                                 (c == '{' && MORE2() && isdigit((uch)PEEK2())) ) )
500                 return;
501         SETERROR(REG_BADRPT);
502 }
503
504 /*
505  - p_str - string (no metacharacters) "parser"
506  == static void p_str(register struct parse *p);
507  */
508 static void
509 p_str(p)
510 register struct parse *p;
511 {
512         (void)REQUIRE(MORE(), REG_EMPTY);
513         while (MORE())
514                 ordinary(p, GETNEXT());
515 }
516
517 /*
518  - p_bre - BRE parser top level, anchoring and concatenation
519  == static void p_bre(register struct parse *p, register int end1, \
520  ==     register int end2);
521  * Giving end1 as OUT essentially eliminates the end1/end2 check.
522  *
523  * This implementation is a bit of a kludge, in that a trailing $ is first
524  * taken as an ordinary character and then revised to be an anchor.  The
525  * only undesirable side effect is that '$' gets included as a character
526  * category in such cases.  This is fairly harmless; not worth fixing.
527  * The amount of lookahead needed to avoid this kludge is excessive.
528  */
529 static void
530 p_bre(p, end1, end2)
531 register struct parse *p;
532 register int end1;              /* first terminating character */
533 register int end2;              /* second terminating character */
534 {
535         register sopno start = HERE();
536         register int first = 1;                 /* first subexpression? */
537         register int wasdollar = 0;
538
539         if (EAT('^')) {
540                 EMIT(OBOL, 0);
541                 p->g->iflags |= USEBOL;
542                 p->g->nbol++;
543         }
544         while (MORE() && !SEETWO(end1, end2)) {
545                 wasdollar = p_simp_re(p, first);
546                 first = 0;
547         }
548         if (wasdollar) {        /* oops, that was a trailing anchor */
549                 DROP(1);
550                 EMIT(OEOL, 0);
551                 p->g->iflags |= USEEOL;
552                 p->g->neol++;
553         }
554
555         (void)REQUIRE(HERE() != start, REG_EMPTY);      /* require nonempty */
556 }
557
558 /*
559  - p_simp_re - parse a simple RE, an atom possibly followed by a repetition
560  == static int p_simp_re(register struct parse *p, int starordinary);
561  */
562 static int                      /* was the simple RE an unbackslashed $? */
563 p_simp_re(p, starordinary)
564 register struct parse *p;
565 int starordinary;               /* is a leading * an ordinary character? */
566 {
567         register int c;
568         register int count;
569         register int count2;
570         register sopno pos;
571         register int i;
572         register sopno subno;
573 #       define  BACKSL  (1<<CHAR_BIT)
574
575         pos = HERE();           /* repetion op, if any, covers from here */
576
577         assert(MORE());         /* caller should have ensured this */
578         c = GETNEXT();
579         if (c == '\\') {
580                 (void)REQUIRE(MORE(), REG_EESCAPE);
581                 c = BACKSL | GETNEXT();
582         }
583         switch (c) {
584         case '.':
585                 if (p->g->cflags&REG_NEWLINE)
586                         nonnewline(p);
587                 else
588                         EMIT(OANY, 0);
589                 break;
590         case '[':
591                 p_bracket(p);
592                 break;
593         case BACKSL|'{':
594                 SETERROR(REG_BADRPT);
595                 break;
596         case BACKSL|'(':
597                 p->g->nsub++;
598                 subno = p->g->nsub;
599                 if (subno < NPAREN)
600                         p->pbegin[subno] = HERE();
601                 EMIT(OLPAREN, subno);
602                 /* the MORE here is an error heuristic */
603                 if (MORE() && !SEETWO('\\', ')'))
604                         p_bre(p, '\\', ')');
605                 if (subno < NPAREN) {
606                         p->pend[subno] = HERE();
607                         assert(p->pend[subno] != 0);
608                 }
609                 EMIT(ORPAREN, subno);
610                 (void)REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
611                 break;
612         case BACKSL|')':        /* should not get here -- must be user */
613         case BACKSL|'}':
614                 SETERROR(REG_EPAREN);
615                 break;
616         case BACKSL|'1':
617         case BACKSL|'2':
618         case BACKSL|'3':
619         case BACKSL|'4':
620         case BACKSL|'5':
621         case BACKSL|'6':
622         case BACKSL|'7':
623         case BACKSL|'8':
624         case BACKSL|'9':
625                 i = (c&~BACKSL) - '0';
626                 assert(i < NPAREN);
627                 if (p->pend[i] != 0) {
628                         assert(i <= p->g->nsub);
629                         EMIT(OBACK_, i);
630                         assert(p->pbegin[i] != 0);
631                         assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
632                         assert(OP(p->strip[p->pend[i]]) == ORPAREN);
633                         (void) dupl(p, p->pbegin[i]+1, p->pend[i]);
634                         EMIT(O_BACK, i);
635                 } else
636                         SETERROR(REG_ESUBREG);
637                 p->g->backrefs = 1;
638                 break;
639         case '*':
640                 (void)REQUIRE(starordinary, REG_BADRPT);
641                 /* FALLTHROUGH */
642         default:
643                 ordinary(p, (char)c);
644                 break;
645         }
646
647         if (EAT('*')) {         /* implemented as +? */
648                 /* this case does not require the (y|) trick, noKLUDGE */
649                 INSERT(OPLUS_, pos);
650                 ASTERN(O_PLUS, pos);
651                 INSERT(OQUEST_, pos);
652                 ASTERN(O_QUEST, pos);
653         } else if (EATTWO('\\', '{')) {
654                 count = p_count(p);
655                 if (EAT(',')) {
656                         if (MORE() && isdigit((uch)PEEK())) {
657                                 count2 = p_count(p);
658                                 (void)REQUIRE(count <= count2, REG_BADBR);
659                         } else          /* single number with comma */
660                                 count2 = INFINITY;
661                 } else          /* just a single number */
662                         count2 = count;
663                 repeat(p, pos, count, count2);
664                 if (!EATTWO('\\', '}')) {       /* error heuristics */
665                         while (MORE() && !SEETWO('\\', '}'))
666                                 NEXT();
667                         (void)REQUIRE(MORE(), REG_EBRACE);
668                         SETERROR(REG_BADBR);
669                 }
670         } else if (c == '$')     /* $ (but not \$) ends it */
671                 return(1);
672
673         return(0);
674 }
675
676 /*
677  - p_count - parse a repetition count
678  == static int p_count(register struct parse *p);
679  */
680 static int                      /* the value */
681 p_count(p)
682 register struct parse *p;
683 {
684         register int count = 0;
685         register int ndigits = 0;
686
687         while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) {
688                 count = count*10 + (GETNEXT() - '0');
689                 ndigits++;
690         }
691
692         (void)REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
693         return(count);
694 }
695
696 /*
697  - p_bracket - parse a bracketed character list
698  == static void p_bracket(register struct parse *p);
699  *
700  * Note a significant property of this code:  if the allocset() did SETERROR,
701  * no set operations are done.
702  */
703 static void
704 p_bracket(p)
705 register struct parse *p;
706 {
707         register cset *cs = allocset(p);
708         register int invert = 0;
709
710         /* Dept of Truly Sickening Special-Case Kludges */
711         if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
712                 EMIT(OBOW, 0);
713                 NEXTn(6);
714                 return;
715         }
716         if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
717                 EMIT(OEOW, 0);
718                 NEXTn(6);
719                 return;
720         }
721
722         if (EAT('^'))
723                 invert++;       /* make note to invert set at end */
724         if (EAT(']'))
725                 CHadd(cs, ']');
726         else if (EAT('-'))
727                 CHadd(cs, '-');
728         while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
729                 p_b_term(p, cs);
730         if (EAT('-'))
731                 CHadd(cs, '-');
732         (void)MUSTEAT(']', REG_EBRACK);
733
734         if (p->error != 0)      /* don't mess things up further */
735                 return;
736
737         if (p->g->cflags&REG_ICASE) {
738                 register int i;
739                 register int ci;
740
741                 for (i = p->g->csetsize - 1; i >= 0; i--)
742                         if (CHIN(cs, i) && isalpha(i)) {
743                                 ci = othercase(i);
744                                 if (ci != i)
745                                         CHadd(cs, ci);
746                         }
747                 if (cs->multis != NULL)
748                         mccase(p, cs);
749         }
750         if (invert) {
751                 register int i;
752
753                 for (i = p->g->csetsize - 1; i >= 0; i--)
754                         if (CHIN(cs, i))
755                                 CHsub(cs, i);
756                         else
757                                 CHadd(cs, i);
758                 if (p->g->cflags&REG_NEWLINE)
759                         CHsub(cs, '\n');
760                 if (cs->multis != NULL)
761                         mcinvert(p, cs);
762         }
763
764         assert(cs->multis == NULL);             /* xxx */
765
766         if (nch(p, cs) == 1) {          /* optimize singleton sets */
767                 ordinary(p, firstch(p, cs));
768                 freeset(p, cs);
769         } else
770                 EMIT(OANYOF, freezeset(p, cs));
771 }
772
773 /*
774  - p_b_term - parse one term of a bracketed character list
775  == static void p_b_term(register struct parse *p, register cset *cs);
776  */
777 static void
778 p_b_term(p, cs)
779 register struct parse *p;
780 register cset *cs;
781 {
782         register char c;
783         register char start, finish;
784         register int i;
785
786         /* classify what we've got */
787         switch ((MORE()) ? PEEK() : '\0') {
788         case '[':
789                 c = (MORE2()) ? PEEK2() : '\0';
790                 break;
791         case '-':
792                 SETERROR(REG_ERANGE);
793                 return;                 /* NOTE RETURN */
794                 break;
795         default:
796                 c = '\0';
797                 break;
798         }
799
800         switch (c) {
801         case ':':               /* character class */
802                 NEXT2();
803                 (void)REQUIRE(MORE(), REG_EBRACK);
804                 c = PEEK();
805                 (void)REQUIRE(c != '-' && c != ']', REG_ECTYPE);
806                 p_b_cclass(p, cs);
807                 (void)REQUIRE(MORE(), REG_EBRACK);
808                 (void)REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
809                 break;
810         case '=':               /* equivalence class */
811                 NEXT2();
812                 (void)REQUIRE(MORE(), REG_EBRACK);
813                 c = PEEK();
814                 (void)REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
815                 p_b_eclass(p, cs);
816                 (void)REQUIRE(MORE(), REG_EBRACK);
817                 (void)REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
818                 break;
819         default:                /* symbol, ordinary character, or range */
820 /* xxx revision needed for multichar stuff */
821                 start = p_b_symbol(p);
822                 if (SEE('-') && MORE2() && PEEK2() != ']') {
823                         /* range */
824                         NEXT();
825                         if (EAT('-'))
826                                 finish = '-';
827                         else
828                                 finish = p_b_symbol(p);
829                 } else
830                         finish = start;
831                 if (start == finish)
832                         CHadd(cs, start);
833                 else {
834 // remove collate stuff --SDM
835 #if 0
836                         if (__collate_load_error) {
837                                 (void)REQUIRE((uch)start <= (uch)finish, REG_ERANGE);
838 #endif 
839                                 for (i = (uch)start; i <= (uch)finish; i++)
840                                         CHadd(cs, i);
841 #if 0
842                         } else {
843                                 (void)REQUIRE(__collate_range_cmp(start, finish) <= 0, REG_ERANGE);
844                                 for (i = CHAR_MIN; i <= CHAR_MAX; i++) {
845                                         if (   __collate_range_cmp(start, i) <= 0
846                                             && __collate_range_cmp(i, finish) <= 0
847                                            )
848                                                 CHadd(cs, i);
849                                 }
850                         }
851 #endif
852                 }
853                 break;
854         }
855 }
856
857 /*
858  - p_b_cclass - parse a character-class name and deal with it
859  == static void p_b_cclass(register struct parse *p, register cset *cs);
860  */
861 static void
862 p_b_cclass(p, cs)
863 register struct parse *p;
864 register cset *cs;
865 {
866         register int c;
867         register char *sp = p->next;
868         register struct cclass *cp;
869         register size_t len;
870
871         while (MORE() && isalpha((uch)PEEK()))
872                 NEXT();
873         len = p->next - sp;
874         for (cp = cclasses; cp->name != NULL; cp++)
875                 if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
876                         break;
877         if (cp->name == NULL) {
878                 /* oops, didn't find it */
879                 SETERROR(REG_ECTYPE);
880                 return;
881         }
882
883         switch (cp->fidx) {
884         case CALNUM:
885                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
886                         if (isalnum((uch)c))
887                                 CHadd(cs, c);
888                 break;
889         case CALPHA:
890                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
891                         if (isalpha((uch)c))
892                                 CHadd(cs, c);
893                 break;
894         case CBLANK:
895                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
896                         if (isblank((uch)c))
897                                 CHadd(cs, c);
898                 break;
899         case CCNTRL:
900                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
901                         if (iscntrl((uch)c))
902                                 CHadd(cs, c);
903                 break;
904         case CDIGIT:
905                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
906                         if (isdigit((uch)c))
907                                 CHadd(cs, c);
908                 break;
909         case CGRAPH:
910                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
911                         if (isgraph((uch)c))
912                                 CHadd(cs, c);
913                 break;
914         case CLOWER:
915                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
916                         if (islower((uch)c))
917                                 CHadd(cs, c);
918                 break;
919         case CPRINT:
920                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
921                         if (isprint((uch)c))
922                                 CHadd(cs, c);
923                 break;
924         case CPUNCT:
925                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
926                         if (ispunct((uch)c))
927                                 CHadd(cs, c);
928                 break;
929         case CSPACE:
930                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
931                         if (isspace((uch)c))
932                                 CHadd(cs, c);
933                 break;
934         case CUPPER:
935                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
936                         if (isupper((uch)c))
937                                 CHadd(cs, c);
938                 break;
939         case CXDIGIT:
940                 for (c = CHAR_MIN; c <= CHAR_MAX; c++)
941                         if (isxdigit((uch)c))
942                                 CHadd(cs, c);
943                 break;
944         }
945 #if 0
946         for (u = cp->multis; *u != '\0'; u += strlen(u) + 1)
947                 MCadd(p, cs, u);
948 #endif
949 }
950
951 /*
952  - p_b_eclass - parse an equivalence-class name and deal with it
953  == static void p_b_eclass(register struct parse *p, register cset *cs);
954  *
955  * This implementation is incomplete. xxx
956  */
957 static void
958 p_b_eclass(p, cs)
959 register struct parse *p;
960 register cset *cs;
961 {
962         register char c;
963
964         c = p_b_coll_elem(p, '=');
965         CHadd(cs, c);
966 }
967
968 /*
969  - p_b_symbol - parse a character or [..]ed multicharacter collating symbol
970  == static char p_b_symbol(register struct parse *p);
971  */
972 static char                     /* value of symbol */
973 p_b_symbol(p)
974 register struct parse *p;
975 {
976         register char value;
977
978         (void)REQUIRE(MORE(), REG_EBRACK);
979         if (!EATTWO('[', '.'))
980                 return(GETNEXT());
981
982         /* collating symbol */
983         value = p_b_coll_elem(p, '.');
984         (void)REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
985         return(value);
986 }
987
988 /*
989  - p_b_coll_elem - parse a collating-element name and look it up
990  == static char p_b_coll_elem(register struct parse *p, int endc);
991  */
992 static char                     /* value of collating element */
993 p_b_coll_elem(p, endc)
994 register struct parse *p;
995 int endc;                       /* name ended by endc,']' */
996 {
997         register char *sp = p->next;
998         register struct cname *cp;
999         register int len;
1000
1001         while (MORE() && !SEETWO(endc, ']'))
1002                 NEXT();
1003         if (!MORE()) {
1004                 SETERROR(REG_EBRACK);
1005                 return(0);
1006         }
1007         len = p->next - sp;
1008         for (cp = cnames; cp->name != NULL; cp++)
1009                 if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0')
1010                         return(cp->code);       /* known name */
1011         if (len == 1)
1012                 return(*sp);    /* single character */
1013         SETERROR(REG_ECOLLATE);                 /* neither */
1014         return(0);
1015 }
1016
1017 /*
1018  - othercase - return the case counterpart of an alphabetic
1019  == static char othercase(int ch);
1020  */
1021 static char                     /* if no counterpart, return ch */
1022 othercase(ch)
1023 int ch;
1024 {
1025         ch = (uch)ch;
1026         assert(isalpha(ch));
1027         if (isupper(ch))
1028                 return(tolower(ch));
1029         else if (islower(ch))
1030                 return(toupper(ch));
1031         else                    /* peculiar, but could happen */
1032                 return(ch);
1033 }
1034
1035 /*
1036  - bothcases - emit a dualcase version of a two-case character
1037  == static void bothcases(register struct parse *p, int ch);
1038  *
1039  * Boy, is this implementation ever a kludge...
1040  */
1041 static void
1042 bothcases(p, ch)
1043 register struct parse *p;
1044 int ch;
1045 {
1046         register char *oldnext = p->next;
1047         register char *oldend = p->end;
1048         char bracket[3];
1049
1050         ch = (uch)ch;
1051         assert(othercase(ch) != ch);    /* p_bracket() would recurse */
1052         p->next = bracket;
1053         p->end = bracket+2;
1054         bracket[0] = ch;
1055         bracket[1] = ']';
1056         bracket[2] = '\0';
1057         p_bracket(p);
1058         assert(p->next == bracket+2);
1059         p->next = oldnext;
1060         p->end = oldend;
1061 }
1062
1063 /*
1064  - ordinary - emit an ordinary character
1065  == static void ordinary(register struct parse *p, register int ch);
1066  */
1067 static void
1068 ordinary(p, ch)
1069 register struct parse *p;
1070 register int ch;
1071 {
1072         register cat_t *cap = p->g->categories;
1073
1074         if ((p->g->cflags&REG_ICASE) && isalpha((uch)ch) && othercase(ch) != ch)
1075                 bothcases(p, ch);
1076         else {
1077                 EMIT(OCHAR, (uch)ch);
1078                 if (cap[ch] == 0)
1079                         cap[ch] = p->g->ncategories++;
1080         }
1081 }
1082
1083 /*
1084  - nonnewline - emit REG_NEWLINE version of OANY
1085  == static void nonnewline(register struct parse *p);
1086  *
1087  * Boy, is this implementation ever a kludge...
1088  */
1089 static void
1090 nonnewline(p)
1091 register struct parse *p;
1092 {
1093         register char *oldnext = p->next;
1094         register char *oldend = p->end;
1095         char bracket[4];
1096
1097         p->next = bracket;
1098         p->end = bracket+3;
1099         bracket[0] = '^';
1100         bracket[1] = '\n';
1101         bracket[2] = ']';
1102         bracket[3] = '\0';
1103         p_bracket(p);
1104         assert(p->next == bracket+3);
1105         p->next = oldnext;
1106         p->end = oldend;
1107 }
1108
1109 /*
1110  - repeat - generate code for a bounded repetition, recursively if needed
1111  == static void repeat(register struct parse *p, sopno start, int from, int to);
1112  */
1113 static void
1114 repeat(p, start, from, to)
1115 register struct parse *p;
1116 sopno start;                    /* operand from here to end of strip */
1117 int from;                       /* repeated from this number */
1118 int to;                         /* to this number of times (maybe INFINITY) */
1119 {
1120         register sopno finish = HERE();
1121 #       define  N       2
1122 #       define  INF     3
1123 #       define  REP(f, t)       ((f)*8 + (t))
1124 #       define  MAP(n)  (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
1125         register sopno copy;
1126
1127         if (p->error != 0)      /* head off possible runaway recursion */
1128                 return;
1129
1130         assert(from <= to);
1131
1132         switch (REP(MAP(from), MAP(to))) {
1133         case REP(0, 0):                 /* must be user doing this */
1134                 DROP(finish-start);     /* drop the operand */
1135                 break;
1136         case REP(0, 1):                 /* as x{1,1}? */
1137         case REP(0, N):                 /* as x{1,n}? */
1138         case REP(0, INF):               /* as x{1,}? */
1139                 /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
1140                 INSERT(OCH_, start);            /* offset is wrong... */
1141                 repeat(p, start+1, 1, to);
1142                 ASTERN(OOR1, start);
1143                 AHEAD(start);                   /* ... fix it */
1144                 EMIT(OOR2, 0);
1145                 AHEAD(THERE());
1146                 ASTERN(O_CH, THERETHERE());
1147                 break;
1148         case REP(1, 1):                 /* trivial case */
1149                 /* done */
1150                 break;
1151         case REP(1, N):                 /* as x?x{1,n-1} */
1152                 /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
1153                 INSERT(OCH_, start);
1154                 ASTERN(OOR1, start);
1155                 AHEAD(start);
1156                 EMIT(OOR2, 0);                  /* offset very wrong... */
1157                 AHEAD(THERE());                 /* ...so fix it */
1158                 ASTERN(O_CH, THERETHERE());
1159                 copy = dupl(p, start+1, finish+1);
1160                 assert(copy == finish+4);
1161                 repeat(p, copy, 1, to-1);
1162                 break;
1163         case REP(1, INF):               /* as x+ */
1164                 INSERT(OPLUS_, start);
1165                 ASTERN(O_PLUS, start);
1166                 break;
1167         case REP(N, N):                 /* as xx{m-1,n-1} */
1168                 copy = dupl(p, start, finish);
1169                 repeat(p, copy, from-1, to-1);
1170                 break;
1171         case REP(N, INF):               /* as xx{n-1,INF} */
1172                 copy = dupl(p, start, finish);
1173                 repeat(p, copy, from-1, to);
1174                 break;
1175         default:                        /* "can't happen" */
1176                 SETERROR(REG_ASSERT);   /* just in case */
1177                 break;
1178         }
1179 }
1180
1181 /*
1182  - seterr - set an error condition
1183  == static int seterr(register struct parse *p, int e);
1184  */
1185 static int                      /* useless but makes type checking happy */
1186 seterr(p, e)
1187 register struct parse *p;
1188 int e;
1189 {
1190         if (p->error == 0)      /* keep earliest error condition */
1191                 p->error = e;
1192         p->next = nuls;         /* try to bring things to a halt */
1193         p->end = nuls;
1194         return(0);              /* make the return value well-defined */
1195 }
1196
1197 /*
1198  - allocset - allocate a set of characters for []
1199  == static cset *allocset(register struct parse *p);
1200  */
1201 static cset *
1202 allocset(p)
1203 register struct parse *p;
1204 {
1205         register int no = p->g->ncsets++;
1206         register size_t nc;
1207         register size_t nbytes;
1208         register cset *cs;
1209         register size_t css = (size_t)p->g->csetsize;
1210         register int i;
1211
1212         if (no >= p->ncsalloc) {        /* need another column of space */
1213                 p->ncsalloc += CHAR_BIT;
1214                 nc = p->ncsalloc;
1215                 assert(nc % CHAR_BIT == 0);
1216                 nbytes = nc / CHAR_BIT * css;
1217                 if (p->g->sets == NULL)
1218                         p->g->sets = (cset *)malloc(nc * sizeof(cset));
1219                 else
1220                         p->g->sets = (cset *)reallocf((char *)p->g->sets,
1221                                                         nc * sizeof(cset));
1222                 if (p->g->setbits == NULL)
1223                         p->g->setbits = (uch *)malloc(nbytes);
1224                 else {
1225                         p->g->setbits = (uch *)reallocf((char *)p->g->setbits,
1226                                                                 nbytes);
1227                         /* xxx this isn't right if setbits is now NULL */
1228                         for (i = 0; i < no; i++)
1229                                 p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);
1230                 }
1231                 if (p->g->sets != NULL && p->g->setbits != NULL)
1232                         (void) memset((char *)p->g->setbits + (nbytes - css),
1233                                                                 0, css);
1234                 else {
1235                         no = 0;
1236                         SETERROR(REG_ESPACE);
1237                         /* caller's responsibility not to do set ops */
1238                 }
1239         }
1240
1241         assert(p->g->sets != NULL);     /* xxx */
1242         cs = &p->g->sets[no];
1243         cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
1244         cs->mask = 1 << ((no) % CHAR_BIT);
1245         cs->hash = 0;
1246         cs->smultis = 0;
1247         cs->multis = NULL;
1248
1249         return(cs);
1250 }
1251
1252 /*
1253  - freeset - free a now-unused set
1254  == static void freeset(register struct parse *p, register cset *cs);
1255  */
1256 static void
1257 freeset(p, cs)
1258 register struct parse *p;
1259 register cset *cs;
1260 {
1261         register int i;
1262         register cset *top = &p->g->sets[p->g->ncsets];
1263         register size_t css = (size_t)p->g->csetsize;
1264
1265         for (i = 0; i < css; i++)
1266                 CHsub(cs, i);
1267         if (cs == top-1)        /* recover only the easy case */
1268                 p->g->ncsets--;
1269 }
1270
1271 /*
1272  - freezeset - final processing on a set of characters
1273  == static int freezeset(register struct parse *p, register cset *cs);
1274  *
1275  * The main task here is merging identical sets.  This is usually a waste
1276  * of time (although the hash code minimizes the overhead), but can win
1277  * big if REG_ICASE is being used.  REG_ICASE, by the way, is why the hash
1278  * is done using addition rather than xor -- all ASCII [aA] sets xor to
1279  * the same value!
1280  */
1281 static int                      /* set number */
1282 freezeset(p, cs)
1283 register struct parse *p;
1284 register cset *cs;
1285 {
1286         register short h = cs->hash;
1287         register int i;
1288         register cset *top = &p->g->sets[p->g->ncsets];
1289         register cset *cs2;
1290         register size_t css = (size_t)p->g->csetsize;
1291
1292         /* look for an earlier one which is the same */
1293         for (cs2 = &p->g->sets[0]; cs2 < top; cs2++)
1294                 if (cs2->hash == h && cs2 != cs) {
1295                         /* maybe */
1296                         for (i = 0; i < css; i++)
1297                                 if (!!CHIN(cs2, i) != !!CHIN(cs, i))
1298                                         break;          /* no */
1299                         if (i == css)
1300                                 break;                  /* yes */
1301                 }
1302
1303         if (cs2 < top) {        /* found one */
1304                 freeset(p, cs);
1305                 cs = cs2;
1306         }
1307
1308         return((int)(cs - p->g->sets));
1309 }
1310
1311 /*
1312  - firstch - return first character in a set (which must have at least one)
1313  == static int firstch(register struct parse *p, register cset *cs);
1314  */
1315 static int                      /* character; there is no "none" value */
1316 firstch(p, cs)
1317 register struct parse *p;
1318 register cset *cs;
1319 {
1320         register int i;
1321         register size_t css = (size_t)p->g->csetsize;
1322
1323         for (i = 0; i < css; i++)
1324                 if (CHIN(cs, i))
1325                         return((char)i);
1326         assert(never);
1327         return(0);              /* arbitrary */
1328 }
1329
1330 /*
1331  - nch - number of characters in a set
1332  == static int nch(register struct parse *p, register cset *cs);
1333  */
1334 static int
1335 nch(p, cs)
1336 register struct parse *p;
1337 register cset *cs;
1338 {
1339         register int i;
1340         register size_t css = (size_t)p->g->csetsize;
1341         register int n = 0;
1342
1343         for (i = 0; i < css; i++)
1344                 if (CHIN(cs, i))
1345                         n++;
1346         return(n);
1347 }
1348
1349 /*
1350  - mcadd - add a collating element to a cset
1351  == static void mcadd(register struct parse *p, register cset *cs, \
1352  ==     register char *cp);
1353  */
1354 static void
1355 mcadd(p, cs, cp)
1356 register struct parse *p;
1357 register cset *cs;
1358 register char *cp;
1359 {
1360         register size_t oldend = cs->smultis;
1361
1362         cs->smultis += strlen(cp) + 1;
1363         if (cs->multis == NULL)
1364                 cs->multis = malloc(cs->smultis);
1365         else
1366                 cs->multis = reallocf(cs->multis, cs->smultis);
1367         if (cs->multis == NULL) {
1368                 SETERROR(REG_ESPACE);
1369                 return;
1370         }
1371
1372         (void) strcpy(cs->multis + oldend - 1, cp);
1373         cs->multis[cs->smultis - 1] = '\0';
1374 }
1375
1376 #if used
1377 /*
1378  - mcsub - subtract a collating element from a cset
1379  == static void mcsub(register cset *cs, register char *cp);
1380  */
1381 static void
1382 mcsub(cs, cp)
1383 register cset *cs;
1384 register char *cp;
1385 {
1386         register char *fp = mcfind(cs, cp);
1387         register size_t len = strlen(fp);
1388
1389         assert(fp != NULL);
1390         (void) memmove(fp, fp + len + 1,
1391                                 cs->smultis - (fp + len + 1 - cs->multis));
1392         cs->smultis -= len;
1393
1394         if (cs->smultis == 0) {
1395                 free(cs->multis);
1396                 cs->multis = NULL;
1397                 return;
1398         }
1399
1400         cs->multis = reallocf(cs->multis, cs->smultis);
1401         assert(cs->multis != NULL);
1402 }
1403
1404 /*
1405  - mcin - is a collating element in a cset?
1406  == static int mcin(register cset *cs, register char *cp);
1407  */
1408 static int
1409 mcin(cs, cp)
1410 register cset *cs;
1411 register char *cp;
1412 {
1413         return(mcfind(cs, cp) != NULL);
1414 }
1415
1416 /*
1417  - mcfind - find a collating element in a cset
1418  == static char *mcfind(register cset *cs, register char *cp);
1419  */
1420 static char *
1421 mcfind(cs, cp)
1422 register cset *cs;
1423 register char *cp;
1424 {
1425         register char *p;
1426
1427         if (cs->multis == NULL)
1428                 return(NULL);
1429         for (p = cs->multis; *p != '\0'; p += strlen(p) + 1)
1430                 if (strcmp(cp, p) == 0)
1431                         return(p);
1432         return(NULL);
1433 }
1434 #endif
1435
1436 /*
1437  - mcinvert - invert the list of collating elements in a cset
1438  == static void mcinvert(register struct parse *p, register cset *cs);
1439  *
1440  * This would have to know the set of possibilities.  Implementation
1441  * is deferred.
1442  */
1443 static void
1444 mcinvert(p, cs)
1445 register struct parse *p;
1446 register cset *cs;
1447 {
1448         assert(cs->multis == NULL);     /* xxx */
1449 }
1450
1451 /*
1452  - mccase - add case counterparts of the list of collating elements in a cset
1453  == static void mccase(register struct parse *p, register cset *cs);
1454  *
1455  * This would have to know the set of possibilities.  Implementation
1456  * is deferred.
1457  */
1458 static void
1459 mccase(p, cs)
1460 register struct parse *p;
1461 register cset *cs;
1462 {
1463         assert(cs->multis == NULL);     /* xxx */
1464 }
1465
1466 /*
1467  - isinsets - is this character in any sets?
1468  == static int isinsets(register struct re_guts *g, int c);
1469  */
1470 static int                      /* predicate */
1471 isinsets(g, c)
1472 register struct re_guts *g;
1473 int c;
1474 {
1475         register uch *col;
1476         register int i;
1477         register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
1478         register unsigned uc = (uch)c;
1479
1480         for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
1481                 if (col[uc] != 0)
1482                         return(1);
1483         return(0);
1484 }
1485
1486 /*
1487  - samesets - are these two characters in exactly the same sets?
1488  == static int samesets(register struct re_guts *g, int c1, int c2);
1489  */
1490 static int                      /* predicate */
1491 samesets(g, c1, c2)
1492 register struct re_guts *g;
1493 int c1;
1494 int c2;
1495 {
1496         register uch *col;
1497         register int i;
1498         register int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT;
1499         register unsigned uc1 = (uch)c1;
1500         register unsigned uc2 = (uch)c2;
1501
1502         for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize)
1503                 if (col[uc1] != col[uc2])
1504                         return(0);
1505         return(1);
1506 }
1507
1508 /*
1509  - categorize - sort out character categories
1510  == static void categorize(struct parse *p, register struct re_guts *g);
1511  */
1512 static void
1513 categorize(p, g)
1514 struct parse *p;
1515 register struct re_guts *g;
1516 {
1517         register cat_t *cats = g->categories;
1518         register int c;
1519         register int c2;
1520         register cat_t cat;
1521
1522         /* avoid making error situations worse */
1523         if (p->error != 0)
1524                 return;
1525
1526         for (c = CHAR_MIN; c <= CHAR_MAX; c++)
1527                 if (cats[c] == 0 && isinsets(g, c)) {
1528                         cat = g->ncategories++;
1529                         cats[c] = cat;
1530                         for (c2 = c+1; c2 <= CHAR_MAX; c2++)
1531                                 if (cats[c2] == 0 && samesets(g, c, c2))
1532                                         cats[c2] = cat;
1533                 }
1534 }
1535
1536 /*
1537  - dupl - emit a duplicate of a bunch of sops
1538  == static sopno dupl(register struct parse *p, sopno start, sopno finish);
1539  */
1540 static sopno                    /* start of duplicate */
1541 dupl(p, start, finish)
1542 register struct parse *p;
1543 sopno start;                    /* from here */
1544 sopno finish;                   /* to this less one */
1545 {
1546         register sopno ret = HERE();
1547         register sopno len = finish - start;
1548
1549         assert(finish >= start);
1550         if (len == 0)
1551                 return(ret);
1552         enlarge(p, p->ssize + len);     /* this many unexpected additions */
1553         assert(p->ssize >= p->slen + len);
1554         (void) memcpy((char *)(p->strip + p->slen),
1555                 (char *)(p->strip + start), (size_t)len*sizeof(sop));
1556         p->slen += len;
1557         return(ret);
1558 }
1559
1560 /*
1561  - doemit - emit a strip operator
1562  == static void doemit(register struct parse *p, sop op, size_t opnd);
1563  *
1564  * It might seem better to implement this as a macro with a function as
1565  * hard-case backup, but it's just too big and messy unless there are
1566  * some changes to the data structures.  Maybe later.
1567  */
1568 static void
1569 doemit(p, op, opnd)
1570 register struct parse *p;
1571 sop op;
1572 size_t opnd;
1573 {
1574         /* avoid making error situations worse */
1575         if (p->error != 0)
1576                 return;
1577
1578         /* deal with oversize operands ("can't happen", more or less) */
1579         assert(opnd < 1<<OPSHIFT);
1580
1581         /* deal with undersized strip */
1582         if (p->slen >= p->ssize)
1583                 enlarge(p, (p->ssize+1) / 2 * 3);       /* +50% */
1584         assert(p->slen < p->ssize);
1585
1586         /* finally, it's all reduced to the easy case */
1587         p->strip[p->slen++] = SOP(op, opnd);
1588 }
1589
1590 /*
1591  - doinsert - insert a sop into the strip
1592  == static void doinsert(register struct parse *p, sop op, size_t opnd, sopno pos);
1593  */
1594 static void
1595 doinsert(p, op, opnd, pos)
1596 register struct parse *p;
1597 sop op;
1598 size_t opnd;
1599 sopno pos;
1600 {
1601         register sopno sn;
1602         register sop s;
1603         register int i;
1604
1605         /* avoid making error situations worse */
1606         if (p->error != 0)
1607                 return;
1608
1609         sn = HERE();
1610         EMIT(op, opnd);         /* do checks, ensure space */
1611         assert(HERE() == sn+1);
1612         s = p->strip[sn];
1613
1614         /* adjust paren pointers */
1615         assert(pos > 0);
1616         for (i = 1; i < NPAREN; i++) {
1617                 if (p->pbegin[i] >= pos) {
1618                         p->pbegin[i]++;
1619                 }
1620                 if (p->pend[i] >= pos) {
1621                         p->pend[i]++;
1622                 }
1623         }
1624
1625         memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
1626                                                 (HERE()-pos-1)*sizeof(sop));
1627         p->strip[pos] = s;
1628 }
1629
1630 /*
1631  - dofwd - complete a forward reference
1632  == static void dofwd(register struct parse *p, sopno pos, sop value);
1633  */
1634 static void
1635 dofwd(p, pos, value)
1636 register struct parse *p;
1637 register sopno pos;
1638 sop value;
1639 {
1640         /* avoid making error situations worse */
1641         if (p->error != 0)
1642                 return;
1643
1644         assert(value < 1<<OPSHIFT);
1645         p->strip[pos] = OP(p->strip[pos]) | value;
1646 }
1647
1648 /*
1649  - enlarge - enlarge the strip
1650  == static void enlarge(register struct parse *p, sopno size);
1651  */
1652 static void
1653 enlarge(p, size)
1654 register struct parse *p;
1655 register sopno size;
1656 {
1657         register sop *sp;
1658
1659         if (p->ssize >= size)
1660                 return;
1661
1662         sp = (sop *)realloc(p->strip, size*sizeof(sop));
1663         if (sp == NULL) {
1664                 SETERROR(REG_ESPACE);
1665                 return;
1666         }
1667         p->strip = sp;
1668         p->ssize = size;
1669 }
1670
1671 /*
1672  - stripsnug - compact the strip
1673  == static void stripsnug(register struct parse *p, register struct re_guts *g);
1674  */
1675 static void
1676 stripsnug(p, g)
1677 register struct parse *p;
1678 register struct re_guts *g;
1679 {
1680         g->nstates = p->slen;
1681         g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
1682         if (g->strip == NULL) {
1683                 SETERROR(REG_ESPACE);
1684                 g->strip = p->strip;
1685         }
1686 }
1687
1688 /*
1689  - findmust - fill in must and mlen with longest mandatory literal string
1690  == static void findmust(register struct parse *p, register struct re_guts *g);
1691  *
1692  * This algorithm could do fancy things like analyzing the operands of |
1693  * for common subsequences.  Someday.  This code is simple and finds most
1694  * of the interesting cases.
1695  *
1696  * Note that must and mlen got initialized during setup.
1697  */
1698 static void
1699 findmust(p, g)
1700 struct parse *p;
1701 register struct re_guts *g;
1702 {
1703         register sop *scan;
1704         sop *start;
1705         register sop *newstart;
1706         register sopno newlen;
1707         register sop s;
1708         register char *cp;
1709         register sopno i;
1710         int offset;
1711         int cs, mccs;
1712
1713         /* avoid making error situations worse */
1714         if (p->error != 0)
1715                 return;
1716
1717         /* Find out if we can handle OANYOF or not */
1718         mccs = 0;
1719         for (cs = 0; cs < g->ncsets; cs++)
1720                 if (g->sets[cs].multis != NULL)
1721                         mccs = 1;
1722
1723         /* find the longest OCHAR sequence in strip */
1724         newlen = 0;
1725         offset = 0;
1726         g->moffset = 0;
1727         scan = g->strip + 1;
1728         do {
1729                 s = *scan++;
1730                 switch (OP(s)) {
1731                 case OCHAR:             /* sequence member */
1732                         if (newlen == 0)                /* new sequence */
1733                                 newstart = scan - 1;
1734                         newlen++;
1735                         break;
1736                 case OPLUS_:            /* things that don't break one */
1737                 case OLPAREN:
1738                 case ORPAREN:
1739                         break;
1740                 case OQUEST_:           /* things that must be skipped */
1741                 case OCH_:
1742                         offset = altoffset(scan, offset, mccs);
1743                         scan--;
1744                         do {
1745                                 scan += OPND(s);
1746                                 s = *scan;
1747                                 /* assert() interferes w debug printouts */
1748                                 if (OP(s) != O_QUEST && OP(s) != O_CH &&
1749                                                         OP(s) != OOR2) {
1750                                         g->iflags |= BAD;
1751                                         return;
1752                                 }
1753                         } while (OP(s) != O_QUEST && OP(s) != O_CH);
1754                         /* fallthrough */
1755                 case OBOW:              /* things that break a sequence */
1756                 case OEOW:
1757                 case OBOL:
1758                 case OEOL:
1759                 case O_QUEST:
1760                 case O_CH:
1761                 case OEND:
1762                         if (newlen > g->mlen) {         /* ends one */
1763                                 start = newstart;
1764                                 g->mlen = newlen;
1765                                 if (offset > -1) {
1766                                         g->moffset += offset;
1767                                         offset = newlen;
1768                                 } else
1769                                         g->moffset = offset;
1770                         } else {
1771                                 if (offset > -1)
1772                                         offset += newlen;
1773                         }
1774                         newlen = 0;
1775                         break;
1776                 case OANY:
1777                         if (newlen > g->mlen) {         /* ends one */
1778                                 start = newstart;
1779                                 g->mlen = newlen;
1780                                 if (offset > -1) {
1781                                         g->moffset += offset;
1782                                         offset = newlen;
1783                                 } else
1784                                         g->moffset = offset;
1785                         } else {
1786                                 if (offset > -1)
1787                                         offset += newlen;
1788                         }
1789                         if (offset > -1)
1790                                 offset++;
1791                         newlen = 0;
1792                         break;
1793                 case OANYOF:            /* may or may not invalidate offset */
1794                         /* First, everything as OANY */
1795                         if (newlen > g->mlen) {         /* ends one */
1796                                 start = newstart;
1797                                 g->mlen = newlen;
1798                                 if (offset > -1) {
1799                                         g->moffset += offset;
1800                                         offset = newlen;
1801                                 } else
1802                                         g->moffset = offset;
1803                         } else {
1804                                 if (offset > -1)
1805                                         offset += newlen;
1806                         }
1807                         if (offset > -1)
1808                                 offset++;
1809                         newlen = 0;
1810                         /* And, now, if we found out we can't deal with
1811                          * it, make offset = -1.
1812                          */
1813                         if (mccs)
1814                                 offset = -1;
1815                         break;
1816                 default:
1817                         /* Anything here makes it impossible or too hard
1818                          * to calculate the offset -- so we give up;
1819                          * save the last known good offset, in case the
1820                          * must sequence doesn't occur later.
1821                          */
1822                         if (newlen > g->mlen) {         /* ends one */
1823                                 start = newstart;
1824                                 g->mlen = newlen;
1825                                 if (offset > -1)
1826                                         g->moffset += offset;
1827                                 else
1828                                         g->moffset = offset;
1829                         }
1830                         offset = -1;
1831                         newlen = 0;
1832                         break;
1833                 }
1834         } while (OP(s) != OEND);
1835
1836         if (g->mlen == 0) {             /* there isn't one */
1837                 g->moffset = -1;
1838                 return;
1839         }
1840
1841         /* turn it into a character string */
1842         g->must = malloc((size_t)g->mlen + 1);
1843         if (g->must == NULL) {          /* argh; just forget it */
1844                 g->mlen = 0;
1845                 g->moffset = -1;
1846                 return;
1847         }
1848         cp = g->must;
1849         scan = start;
1850         for (i = g->mlen; i > 0; i--) {
1851                 while (OP(s = *scan++) != OCHAR)
1852                         continue;
1853                 assert(cp < g->must + g->mlen);
1854                 *cp++ = (char)OPND(s);
1855         }
1856         assert(cp == g->must + g->mlen);
1857         *cp++ = '\0';           /* just on general principles */
1858 }
1859
1860 /*
1861  - altoffset - choose biggest offset among multiple choices
1862  == static int altoffset(sop *scan, int offset, int mccs);
1863  *
1864  * Compute, recursively if necessary, the largest offset among multiple
1865  * re paths.
1866  */
1867 static int
1868 altoffset(scan, offset, mccs)
1869 sop *scan;
1870 int offset;
1871 int mccs;
1872 {
1873         int largest;
1874         int try;
1875         sop s;
1876
1877         /* If we gave up already on offsets, return */
1878         if (offset == -1)
1879                 return -1;
1880
1881         largest = 0;
1882         try = 0;
1883         s = *scan++;
1884         while (OP(s) != O_QUEST && OP(s) != O_CH) {
1885                 switch (OP(s)) {
1886                 case OOR1:
1887                         if (try > largest)
1888                                 largest = try;
1889                         try = 0;
1890                         break;
1891                 case OQUEST_:
1892                 case OCH_:
1893                         try = altoffset(scan, try, mccs);
1894                         if (try == -1)
1895                                 return -1;
1896                         scan--;
1897                         do {
1898                                 scan += OPND(s);
1899                                 s = *scan;
1900                                 if (OP(s) != O_QUEST && OP(s) != O_CH &&
1901                                                         OP(s) != OOR2)
1902                                         return -1;
1903                         } while (OP(s) != O_QUEST && OP(s) != O_CH);
1904                         /* We must skip to the next position, or we'll
1905                          * leave altoffset() too early.
1906                          */
1907                         scan++;
1908                         break;
1909                 case OANYOF:
1910                         if (mccs)
1911                                 return -1;
1912                 case OCHAR:
1913                 case OANY:
1914                         try++;
1915                 case OBOW:
1916                 case OEOW:
1917                 case OLPAREN:
1918                 case ORPAREN:
1919                 case OOR2:
1920                         break;
1921                 default:
1922                         try = -1;
1923                         break;
1924                 }
1925                 if (try == -1)
1926                         return -1;
1927                 s = *scan++;
1928         }
1929
1930         if (try > largest)
1931                 largest = try;
1932
1933         return largest+offset;
1934 }
1935
1936 /*
1937  - computejumps - compute char jumps for BM scan
1938  == static void computejumps(register struct parse *p, register struct re_guts *g);
1939  *
1940  * This algorithm assumes g->must exists and is has size greater than
1941  * zero. It's based on the algorithm found on Computer Algorithms by
1942  * Sara Baase.
1943  *
1944  * A char jump is the number of characters one needs to jump based on
1945  * the value of the character from the text that was mismatched.
1946  */
1947 static void
1948 computejumps(p, g)
1949 struct parse *p;
1950 struct re_guts *g;
1951 {
1952         int ch;
1953         int mindex;
1954
1955         /* Avoid making errors worse */
1956         if (p->error != 0)
1957                 return;
1958
1959         g->charjump = (int*) malloc((NC + 1) * sizeof(int));
1960         if (g->charjump == NULL)        /* Not a fatal error */
1961                 return;
1962         /* Adjust for signed chars, if necessary */
1963         g->charjump = &g->charjump[-(CHAR_MIN)];
1964
1965         /* If the character does not exist in the pattern, the jump
1966          * is equal to the number of characters in the pattern.
1967          */
1968         for (ch = CHAR_MIN; ch < (CHAR_MAX + 1); ch++)
1969                 g->charjump[ch] = g->mlen;
1970
1971         /* If the character does exist, compute the jump that would
1972          * take us to the last character in the pattern equal to it
1973          * (notice that we match right to left, so that last character
1974          * is the first one that would be matched).
1975          */
1976         for (mindex = 0; mindex < g->mlen; mindex++)
1977                 g->charjump[g->must[mindex]] = g->mlen - mindex - 1;
1978 }
1979
1980 /*
1981  - computematchjumps - compute match jumps for BM scan
1982  == static void computematchjumps(register struct parse *p, register struct re_guts *g);
1983  *
1984  * This algorithm assumes g->must exists and is has size greater than
1985  * zero. It's based on the algorithm found on Computer Algorithms by
1986  * Sara Baase.
1987  *
1988  * A match jump is the number of characters one needs to advance based
1989  * on the already-matched suffix.
1990  * Notice that all values here are minus (g->mlen-1), because of the way
1991  * the search algorithm works.
1992  */
1993 static void
1994 computematchjumps(p, g)
1995 struct parse *p;
1996 struct re_guts *g;
1997 {
1998         int mindex;             /* General "must" iterator */
1999         int suffix;             /* Keeps track of matching suffix */
2000         int ssuffix;            /* Keeps track of suffixes' suffix */
2001         int* pmatches;          /* pmatches[k] points to the next i
2002                                  * such that i+1...mlen is a substring
2003                                  * of k+1...k+mlen-i-1
2004                                  */
2005
2006         /* Avoid making errors worse */
2007         if (p->error != 0)
2008                 return;
2009
2010         pmatches = (int*) malloc(g->mlen * sizeof(unsigned int));
2011         if (pmatches == NULL) {
2012                 g->matchjump = NULL;
2013                 return;
2014         }
2015
2016         g->matchjump = (int*) malloc(g->mlen * sizeof(unsigned int));
2017         if (g->matchjump == NULL)       /* Not a fatal error */
2018                 return;
2019
2020         /* Set maximum possible jump for each character in the pattern */
2021         for (mindex = 0; mindex < g->mlen; mindex++)
2022                 g->matchjump[mindex] = 2*g->mlen - mindex - 1;
2023
2024         /* Compute pmatches[] */
2025         for (mindex = g->mlen - 1, suffix = g->mlen; mindex >= 0;
2026             mindex--, suffix--) {
2027                 pmatches[mindex] = suffix;
2028
2029                 /* If a mismatch is found, interrupting the substring,
2030                  * compute the matchjump for that position. If no
2031                  * mismatch is found, then a text substring mismatched
2032                  * against the suffix will also mismatch against the
2033                  * substring.
2034                  */
2035                 while (suffix < g->mlen
2036                     && g->must[mindex] != g->must[suffix]) {
2037                         g->matchjump[suffix] = MIN(g->matchjump[suffix],
2038                             g->mlen - mindex - 1);
2039                         suffix = pmatches[suffix];
2040                 }
2041         }
2042
2043         /* Compute the matchjump up to the last substring found to jump
2044          * to the beginning of the largest must pattern prefix matching
2045          * it's own suffix.
2046          */
2047         for (mindex = 0; mindex <= suffix; mindex++)
2048                 g->matchjump[mindex] = MIN(g->matchjump[mindex],
2049                     g->mlen + suffix - mindex);
2050
2051         ssuffix = pmatches[suffix];
2052         while (suffix < g->mlen) {
2053                 while (suffix <= ssuffix && suffix < g->mlen) {
2054                         g->matchjump[suffix] = MIN(g->matchjump[suffix],
2055                             g->mlen + ssuffix - suffix);
2056                         suffix++;
2057                 }
2058                 ssuffix = pmatches[ssuffix];
2059         }
2060
2061         free(pmatches);
2062 }
2063
2064 /*
2065  - pluscount - count + nesting
2066  == static sopno pluscount(register struct parse *p, register struct re_guts *g);
2067  */
2068 static sopno                    /* nesting depth */
2069 pluscount(p, g)
2070 struct parse *p;
2071 register struct re_guts *g;
2072 {
2073         register sop *scan;
2074         register sop s;
2075         register sopno plusnest = 0;
2076         register sopno maxnest = 0;
2077
2078         if (p->error != 0)
2079                 return(0);      /* there may not be an OEND */
2080
2081         scan = g->strip + 1;
2082         do {
2083                 s = *scan++;
2084                 switch (OP(s)) {
2085                 case OPLUS_:
2086                         plusnest++;
2087                         break;
2088                 case O_PLUS:
2089                         if (plusnest > maxnest)
2090                                 maxnest = plusnest;
2091                         plusnest--;
2092                         break;
2093                 }
2094         } while (OP(s) != OEND);
2095         if (plusnest != 0)
2096                 g->iflags |= BAD;
2097         return(maxnest);
2098 }