164f880374c8a599d61d92dc148760f72411b6b0
[oweals/busybox.git] / regexp.c
1 /* regexp.c */
2
3 #include "internal.h"
4 #include "regexp.h"
5 #include <setjmp.h>
6 #include <stdio.h>
7 #include <ctype.h>
8
9
10 #if ( defined BB_GREP || defined BB_FIND  || defined BB_SED)
11
12 /* This also tries to find a needle in a haystack, but uses
13  * real regular expressions....  The fake regular expression
14  * version of find_match lives in utility.c.  Using this version
15  * will add 3.9k to busybox...
16  *  -Erik Andersen
17  */
18 extern int find_match(char *haystack, char *needle, int ignoreCase)
19 {
20     int status;
21     struct regexp*  re;
22     re = regcomp( needle);
23     status = regexec(re, haystack, FALSE, ignoreCase);
24     free( re);
25     return( status);
26 }
27
28 #if defined BB_SED
29 /* This performs substitutions after a regexp match has been found.  
30  * The new string is returned.  It is malloc'ed, and do must be freed. */
31 extern int replace_match(char *haystack, char *needle, char *newNeedle, int ignoreCase)
32 {
33     int status;
34     struct regexp*  re;
35     char *s, buf[BUF_SIZE], *d = buf;
36
37     re = regcomp( needle);
38     status = regexec(re, haystack, FALSE, ignoreCase);
39     if (status==TRUE) {
40         s=haystack;
41
42         do {
43             /* copy stuff from before the match */
44             while (s < re->startp[0])
45                 *d++ = *s++;
46             /* substitute for the matched part */
47             regsub(re, newNeedle, d);
48             s = re->endp[0];
49             d += strlen(d);
50         } while (regexec(re, s, FALSE, ignoreCase) == TRUE);
51          /* copy stuff from after the match */
52         while ( (*d++ = *s++) ) {}
53         d[-1] = '\n';
54         d[0] = '\0';
55         strcpy(haystack, buf);
56     }
57     free( re);
58     return( status);
59 }
60 #endif
61
62
63 /* code swiped from elvis-tiny 1.4 (a clone of vi) and adjusted to 
64  * suit the needs of busybox by Erik Andersen.
65  *
66  * From the README:
67  * "Elvis is freely redistributable, in either source form or executable form.
68  * There are no restrictions on how you may use it".
69  * Elvis was written by Steve Kirkendall <kirkenda@cs.pdx.edu>
70  *
71  *
72  * This file contains the code that compiles regular expressions and executes
73  * them.  It supports the same syntax and features as vi's regular expression
74  * code.  Specifically, the meta characters are:
75  *      ^       matches the beginning of a line
76  *      $       matches the end of a line
77  *      \<      matches the beginning of a word
78  *      \>      matches the end of a word
79  *      .       matches any single character
80  *      []      matches any character in a character class
81  *      \(      delimits the start of a subexpression
82  *      \)      delimits the end of a subexpression
83  *      *       repeats the preceding 0 or more times
84  * NOTE: You cannot follow a \) with a *.
85  *
86  * The physical structure of a compiled RE is as follows:
87  *      - First, there is a one-byte value that says how many character classes
88  *        are used in this regular expression
89  *      - Next, each character class is stored as a bitmap that is 256 bits
90  *        (32 bytes) long.
91  *      - A mixture of literal characters and compiled meta characters follows.
92  *        This begins with M_BEGIN(0) and ends with M_END(0).  All meta chars
93  *        are stored as a \n followed by a one-byte code, so they take up two
94  *        bytes apiece.  Literal characters take up one byte apiece.  \n can't
95  *        be used as a literal character.
96  *
97  */
98
99
100
101 static char *previous;  /* the previous regexp, used when null regexp is given */
102 static char *previous1; /* a copy of the text from the previous substitution for regsub()*/
103
104
105 /* These are used to classify or recognize meta-characters */
106 #define META            '\0'
107 #define BASE_META(m)    ((m) - 256)
108 #define INT_META(c)     ((c) + 256)
109 #define IS_META(m)      ((m) >= 256)
110 #define IS_CLASS(m)     ((m) >= M_CLASS(0) && (m) <= M_CLASS(9))
111 #define IS_START(m)     ((m) >= M_START(0) && (m) <= M_START(9))
112 #define IS_END(m)       ((m) >= M_END(0) && (m) <= M_END(9))
113 #define IS_CLOSURE(m)   ((m) >= M_SPLAT && (m) <= M_QMARK)
114 #define ADD_META(s,m)   (*(s)++ = META, *(s)++ = BASE_META(m))
115 #define GET_META(s)     (*(s) == META ? INT_META(*++(s)) : *s)
116
117 /* These are the internal codes used for each type of meta-character */
118 #define M_BEGLINE       256             /* internal code for ^ */
119 #define M_ENDLINE       257             /* internal code for $ */
120 #define M_BEGWORD       258             /* internal code for \< */
121 #define M_ENDWORD       259             /* internal code for \> */
122 #define M_ANY           260             /* internal code for . */
123 #define M_SPLAT         261             /* internal code for * */
124 #define M_PLUS          262             /* internal code for \+ */
125 #define M_QMARK         263             /* internal code for \? */
126 #define M_CLASS(n)      (264+(n))       /* internal code for [] */
127 #define M_START(n)      (274+(n))       /* internal code for \( */
128 #define M_END(n)        (284+(n))       /* internal code for \) */
129
130 /* These are used during compilation */
131 static int      class_cnt;      /* used to assign class IDs */
132 static int      start_cnt;      /* used to assign start IDs */
133 static int      end_stk[NSUBEXP];/* used to assign end IDs */
134 static int      end_sp;
135 static char     *retext;        /* points to the text being compiled */
136
137 /* error-handling stuff */
138 jmp_buf errorhandler;
139 #define FAIL(why)       fprintf(stderr, why); longjmp(errorhandler, 1)
140
141
142
143
144 /* This function builds a bitmap for a particular class */
145 /* text -- start of the class */
146 /* bmap -- the bitmap */
147 static char *makeclass(char* text, char* bmap)
148 {
149         int             i;
150         int             complement = 0;
151
152
153         /* zero the bitmap */
154         for (i = 0; bmap && i < 32; i++)
155         {
156                 bmap[i] = 0;
157         }
158
159         /* see if we're going to complement this class */
160         if (*text == '^')
161         {
162                 text++;
163                 complement = 1;
164         }
165
166         /* add in the characters */
167         while (*text && *text != ']')
168         {
169                 /* is this a span of characters? */
170                 if (text[1] == '-' && text[2])
171                 {
172                         /* spans can't be backwards */
173                         if (text[0] > text[2])
174                         {
175                                 FAIL("Backwards span in []");
176                         }
177
178                         /* add each character in the span to the bitmap */
179                         for (i = text[0]; bmap && i <= text[2]; i++)
180                         {
181                                 bmap[i >> 3] |= (1 << (i & 7));
182                         }
183
184                         /* move past this span */
185                         text += 3;
186                 }
187                 else
188                 {
189                         /* add this single character to the span */
190                         i = *text++;
191                         if (bmap)
192                         {
193                                 bmap[i >> 3] |= (1 << (i & 7));
194                         }
195                 }
196         }
197
198         /* make sure the closing ] is missing */
199         if (*text++ != ']')
200         {
201                 FAIL("] missing");
202         }
203
204         /* if we're supposed to complement this class, then do so */
205         if (complement && bmap)
206         {
207                 for (i = 0; i < 32; i++)
208                 {
209                         bmap[i] = ~bmap[i];
210                 }
211         }
212
213         return text;
214 }
215
216
217
218
219 /* This function gets the next character or meta character from a string.
220  * The pointer is incremented by 1, or by 2 for \-quoted characters.  For [],
221  * a bitmap is generated via makeclass() (if re is given), and the
222  * character-class text is skipped.
223  */
224 static int gettoken(sptr, re)
225         char    **sptr;
226         regexp  *re;
227 {
228         int     c;
229
230         c = **sptr;
231         ++*sptr;
232         if (c == '\\')
233         {
234                 c = **sptr;
235                 ++*sptr;
236                 switch (c)
237                 {
238                   case '<':
239                         return M_BEGWORD;
240
241                   case '>':
242                         return M_ENDWORD;
243
244                   case '(':
245                         if (start_cnt >= NSUBEXP)
246                         {
247                                 FAIL("Too many \\(s");
248                         }
249                         end_stk[end_sp++] = start_cnt;
250                         return M_START(start_cnt++);
251
252                   case ')':
253                         if (end_sp <= 0)
254                         {
255                                 FAIL("Mismatched \\)");
256                         }
257                         return M_END(end_stk[--end_sp]);
258
259                   case '*':
260                         return M_SPLAT;
261
262                   case '.':
263                         return M_ANY;
264
265                   case '+':
266                         return M_PLUS;
267
268                   case '?':
269                         return M_QMARK;
270
271                   default:
272                         return c;
273                 }
274         }
275         else {
276                 switch (c)
277                 {
278                   case '^':
279                         if (*sptr == retext + 1)
280                         {
281                                 return M_BEGLINE;
282                         }
283                         return c;
284
285                   case '$':
286                         if (!**sptr)
287                         {
288                                 return M_ENDLINE;
289                         }
290                         return c;
291
292                   case '.':
293                         return M_ANY;
294
295                   case '*':
296                         return M_SPLAT;
297
298                   case '[':
299                         /* make sure we don't have too many classes */
300                         if (class_cnt >= 10)
301                         {
302                                 FAIL("Too many []s");
303                         }
304
305                         /* process the character list for this class */
306                         if (re)
307                         {
308                                 /* generate the bitmap for this class */
309                                 *sptr = makeclass(*sptr, re->program + 1 + 32 * class_cnt);
310                         }
311                         else
312                         {
313                                 /* skip to end of the class */
314                                 *sptr = makeclass(*sptr, (char *)0);
315                         }
316                         return M_CLASS(class_cnt++);
317
318                   default:
319                         return c;
320                 }
321         }
322         /*NOTREACHED*/
323 }
324
325
326
327
328 /* This function calculates the number of bytes that will be needed for a
329  * compiled RE.  Its argument is the uncompiled version.  It is not clever
330  * about catching syntax errors; that is done in a later pass.
331  */
332 static unsigned calcsize(text)
333         char            *text;
334 {
335         unsigned        size;
336         int             token;
337
338         retext = text;
339         class_cnt = 0;
340         start_cnt = 1;
341         end_sp = 0;
342         size = 5;
343         while ((token = gettoken(&text, (regexp *)0)) != 0)
344         {
345                 if (IS_CLASS(token))
346                 {
347                         size += 34;
348                 }
349                 else if (IS_META(token))
350                 {
351                         size += 2;
352                 }
353                 else
354                 {
355                         size++;
356                 }
357         }
358
359         return size;
360 }
361
362
363
364 /*---------------------------------------------------------------------------*/
365
366
367 /* This function checks for a match between a character and a token which is
368  * known to represent a single character.  It returns 0 if they match, or
369  * 1 if they don't.
370  */
371 static int match1(regexp* re, char ch, int token, int ignoreCase)
372 {
373         if (!ch)
374         {
375                 /* the end of a line can't match any RE of width 1 */
376                 return 1;
377         }
378         if (token == M_ANY)
379         {
380                 return 0;
381         }
382         else if (IS_CLASS(token))
383         {
384                 if (re->program[1 + 32 * (token - M_CLASS(0)) + (ch >> 3)] & (1 << (ch & 7)))
385                         return 0;
386         }
387         else if (ch == token
388                 || (ignoreCase==TRUE && isupper(ch) && tolower(ch) == token))
389         {
390                 return 0;
391         }
392         return 1;
393 }
394
395
396
397 /* This function checks characters up to and including the next closure, at
398  * which point it does a recursive call to check the rest of it.  This function
399  * returns 0 if everything matches, or 1 if something doesn't match.
400  */
401 /* re   -- the regular expression */
402 /* str  -- the string */
403 /* prog -- a portion of re->program, an compiled RE */
404 /* here -- a portion of str, the string to compare it to */
405 static int match(regexp* re, char* str, char* prog, char* here, int ignoreCase)
406 {
407         int             token;
408         int             nmatched;
409         int             closure;
410
411         for (token = GET_META(prog); !IS_CLOSURE(token); prog++, token = GET_META(prog))
412         {
413                 switch (token)
414                 {
415                 /*case M_BEGLINE: can't happen; re->bol is used instead */
416                   case M_ENDLINE:
417                         if (*here)
418                                 return 1;
419                         break;
420
421                   case M_BEGWORD:
422                         if (here != str &&
423                            (here[-1] == '_' ||
424                              (isascii(here[-1]) && isalnum(here[-1]))))
425                                 return 1;
426                         break;
427
428                   case M_ENDWORD:
429                         if ((here[0] == '_' || isascii(here[0])) && isalnum(here[0]))
430                                 return 1;
431                         break;
432
433                   case M_START(0):
434                   case M_START(1):
435                   case M_START(2):
436                   case M_START(3):
437                   case M_START(4):
438                   case M_START(5):
439                   case M_START(6):
440                   case M_START(7):
441                   case M_START(8):
442                   case M_START(9):
443                         re->startp[token - M_START(0)] = (char *)here;
444                         break;
445
446                   case M_END(0):
447                   case M_END(1):
448                   case M_END(2):
449                   case M_END(3):
450                   case M_END(4):
451                   case M_END(5):
452                   case M_END(6):
453                   case M_END(7):
454                   case M_END(8):
455                   case M_END(9):
456                         re->endp[token - M_END(0)] = (char *)here;
457                         if (token == M_END(0))
458                         {
459                                 return 0;
460                         }
461                         break;
462
463                   default: /* literal, M_CLASS(n), or M_ANY */
464                         if (match1(re, *here, token, ignoreCase) != 0)
465                                 return 1;
466                         here++;
467                 }
468         }
469
470         /* C L O S U R E */
471
472         /* step 1: see what we have to match against, and move "prog" to point
473          * the the remainder of the compiled RE.
474          */
475         closure = token;
476         prog++, token = GET_META(prog);
477         prog++;
478
479         /* step 2: see how many times we can match that token against the string */
480         for (nmatched = 0;
481              (closure != M_QMARK || nmatched < 1) && *here && match1(re, *here, token, ignoreCase) == 0;
482              nmatched++, here++)
483         {
484         }
485
486         /* step 3: try to match the remainder, and back off if it doesn't */
487         while (nmatched >= 0 && match(re, str, prog, here, ignoreCase) != 0)
488         {
489                 nmatched--;
490                 here--;
491         }
492
493         /* so how did it work out? */
494         if (nmatched >= ((closure == M_PLUS) ? 1 : 0))
495                 return 0;
496         return 1;
497 }
498
499
500 /* This function compiles a regexp. */
501 extern regexp *regcomp(char* text)
502 {
503         int             needfirst;
504         unsigned        size;
505         int             token;
506         int             peek;
507         char            *build;
508         regexp          *re;
509
510
511         /* prepare for error handling */
512         re = (regexp *)0;
513         if (setjmp(errorhandler))
514         {
515                 if (re)
516                 {
517                         free(re);
518                 }
519                 return (regexp *)0;
520         }
521
522         /* if an empty regexp string was given, use the previous one */
523         if (*text == 0)
524         {
525                 if (!previous)
526                 {
527                         FAIL("No previous RE");
528                 }
529                 text = previous;
530         }
531         else /* non-empty regexp given, so remember it */
532         {
533                 if (previous)
534                         free(previous);
535                 previous = (char *)malloc((unsigned)(strlen(text) + 1));
536                 if (previous)
537                         strcpy(previous, text);
538         }
539
540         /* allocate memory */
541         class_cnt = 0;
542         start_cnt = 1;
543         end_sp = 0;
544         retext = text;
545         size = calcsize(text) + sizeof(regexp);
546         re = (regexp *)malloc((unsigned)size);
547
548         if (!re)
549         {
550                 FAIL("Not enough memory for this RE");
551         }
552
553         /* compile it */
554         build = &re->program[1 + 32 * class_cnt];
555         re->program[0] = class_cnt;
556         for (token = 0; token < NSUBEXP; token++)
557         {
558                 re->startp[token] = re->endp[token] = (char *)0;
559         }
560         re->first = 0;
561         re->bol = 0;
562         re->minlen = 0;
563         needfirst = 1;
564         class_cnt = 0;
565         start_cnt = 1;
566         end_sp = 0;
567         retext = text;
568         for (token = M_START(0), peek = gettoken(&text, re);
569              token;
570              token = peek, peek = gettoken(&text, re))
571         {
572                 /* special processing for the closure operator */
573                 if (IS_CLOSURE(peek))
574                 {
575                         /* detect misuse of closure operator */
576                         if (IS_START(token))
577                         {
578                                 FAIL("* or \\+ or \\? follows nothing");
579                         }
580                         else if (IS_META(token) && token != M_ANY && !IS_CLASS(token))
581                         {
582                                 FAIL("* or \\+ or \\? can only follow a normal character or . or []");
583                         }
584
585                         /* it is okay -- make it prefix instead of postfix */
586                         ADD_META(build, peek);
587
588                         /* take care of "needfirst" - is this the first char? */
589                         if (needfirst && peek == M_PLUS && !IS_META(token))
590                         {
591                                 re->first = token;
592                         }
593                         needfirst = 0;
594
595                         /* we used "peek" -- need to refill it */
596                         peek = gettoken(&text, re);
597                         if (IS_CLOSURE(peek))
598                         {
599                                 FAIL("* or \\+ or \\? doubled up");
600                         }
601                 }
602                 else if (!IS_META(token))
603                 {
604                         /* normal char is NOT argument of closure */
605                         if (needfirst)
606                         {
607                                 re->first = token;
608                                 needfirst = 0;
609                         }
610                         re->minlen++;
611                 }
612                 else if (token == M_ANY || IS_CLASS(token))
613                 {
614                         /* . or [] is NOT argument of closure */
615                         needfirst = 0;
616                         re->minlen++;
617                 }
618
619                 /* the "token" character is not closure -- process it normally */
620                 if (token == M_BEGLINE)
621                 {
622                         /* set the BOL flag instead of storing M_BEGLINE */
623                         re->bol = 1;
624                 }
625                 else if (IS_META(token))
626                 {
627                         ADD_META(build, token);
628                 }
629                 else
630                 {
631                         *build++ = token;
632                 }
633         }
634
635         /* end it with a \) which MUST MATCH the opening \( */
636         ADD_META(build, M_END(0));
637         if (end_sp > 0)
638         {
639                 FAIL("Not enough \\)s");
640         }
641
642         return re;
643 }
644
645
646
647
648 /* This function searches through a string for text that matches an RE. */
649 /* re  -- the compiled regexp to search for */
650 /* str -- the string to search through */
651 /* bol -- does str start at the beginning of a line? (boolean) */
652 /* ignoreCase -- ignoreCase or not */
653 extern int regexec(struct regexp* re, char* str, int bol, int ignoreCase)
654 {
655         char    *prog;  /* the entry point of re->program */
656         int     len;    /* length of the string */
657         char    *here;
658
659         /* if must start at the beginning of a line, and this isn't, then fail */
660         if (re->bol && bol==TRUE)
661         {
662                 return FALSE;
663         }
664
665         len = strlen(str);
666         prog = re->program + 1 + 32 * re->program[0];
667
668         /* search for the RE in the string */
669         if (re->bol)
670         {
671                 /* must occur at BOL */
672                 if ((re->first
673                         && match1(re, *(char *)str, re->first, ignoreCase))/* wrong first letter? */
674                  || len < re->minlen                    /* not long enough? */
675                  || match(re, (char *)str, prog, str, ignoreCase))      /* doesn't match? */
676                         return FALSE;                   /* THEN FAIL! */
677         }
678         else if (ignoreCase == FALSE)
679         {
680                 /* can occur anywhere in the line, noignorecase */
681                 for (here = (char *)str;
682                      (re->first && re->first != *here)
683                         || match(re, (char *)str, prog, here, ignoreCase);
684                      here++, len--)
685                 {
686                         if (len < re->minlen)
687                                 return FALSE;
688                 }
689         }
690         else
691         {
692                 /* can occur anywhere in the line, ignorecase */
693                 for (here = (char *)str;
694                      (re->first && match1(re, *here, (int)re->first, ignoreCase))
695                         || match(re, (char *)str, prog, here, ignoreCase);
696                      here++, len--)
697                 {
698                         if (len < re->minlen)
699                                 return FALSE;
700                 }
701         }
702
703         /* if we didn't fail, then we must have succeeded */
704         return TRUE;
705 }
706
707
708
709
710 #if defined BB_SED
711 /* This performs substitutions after a regexp match has been found.  */
712 extern void regsub(regexp* re, char* src, char* dst)
713 {
714         char    *cpy;
715         char    *end;
716         char    c;
717         char            *start;
718         int             mod;
719
720         mod = 0;
721
722         start = src;
723         while ((c = *src++) != '\0')
724         {
725                 /* recognize any meta characters */
726                 if (c == '&')
727                 {
728                         cpy = re->startp[0];
729                         end = re->endp[0];
730                 }
731                 else if (c == '~')
732                 {
733                         cpy = previous1;
734                         if (cpy)
735                                 end = cpy + strlen(cpy);
736                 }
737                 else
738                 if (c == '\\')
739                 {
740                         c = *src++;
741                         switch (c)
742                         {
743                           case '0':
744                           case '1':
745                           case '2':
746                           case '3':
747                           case '4':
748                           case '5':
749                           case '6':
750                           case '7':
751                           case '8':
752                           case '9':
753                                 /* \0 thru \9 mean "copy subexpression" */
754                                 c -= '0';
755                                 cpy = re->startp[(int)c];
756                                 end = re->endp[(int)c];
757                                 break;
758                           case 'U':
759                           case 'u':
760                           case 'L':
761                           case 'l':
762                                 /* \U and \L mean "convert to upper/lowercase" */
763                                 mod = c;
764                                 continue;
765
766                           case 'E':
767                           case 'e':
768                                 /* \E ends the \U or \L */
769                                 mod = 0;
770                                 continue;
771                           case '&':
772                                 /* "\&" means "original text" */
773                                 *dst++ = c;
774                                 continue;
775
776                           case '~':
777                                 /* "\~" means "previous text, if any" */
778                                 *dst++ = c;
779                                 continue;
780                           default:
781                                 /* ordinary char preceded by backslash */
782                                 *dst++ = c;
783                                 continue;
784                         }
785                 }
786                 else
787                 {
788                         /* ordinary character, so just copy it */
789                         *dst++ = c;
790                         continue;
791                 }
792
793                 /* Note: to reach this point in the code, we must have evaded
794                  * all "continue" statements.  To do that, we must have hit
795                  * a metacharacter that involves copying.
796                  */
797
798                 /* if there is nothing to copy, loop */
799                 if (!cpy)
800                         continue;
801
802                 /* copy over a portion of the original */
803                 while (cpy < end)
804                 {
805                         switch (mod)
806                         {
807                           case 'U':
808                           case 'u':
809                                 /* convert to uppercase */
810                                 if (isascii(*cpy) && islower(*cpy))
811                                 {
812                                         *dst++ = toupper(*cpy);
813                                         cpy++;
814                                 }
815                                 else
816                                 {
817                                         *dst++ = *cpy++;
818                                 }
819                                 break;
820
821                           case 'L':
822                           case 'l':
823                                 /* convert to lowercase */
824                                 if (isascii(*cpy) && isupper(*cpy))
825                                 {
826                                         *dst++ = tolower(*cpy);
827                                         cpy++;
828                                 }
829                                 else
830                                 {
831                                         *dst++ = *cpy++;
832                                 }
833                                 break;
834
835                           default:
836                                 /* copy without any conversion */
837                                 *dst++ = *cpy++;
838                         }
839
840                         /* \u and \l end automatically after the first char */
841                         if (mod && (mod == 'u' || mod == 'l'))
842                         {
843                                 mod = 0;
844                         }
845                 }
846         }
847         *dst = '\0';
848
849         /* remember what text we inserted this time */
850         if (previous1)
851                 free(previous1);
852         previous1 = (char *)malloc((unsigned)(strlen(start) + 1));
853         if (previous1)
854                 strcpy(previous1, start);
855 }
856 #endif
857
858 #endif /* BB_REGEXP */
859
860