2 Copyright (c) 1995-1998 by Cisco systems, Inc.
4 Permission to use, copy, modify, and distribute this software for
5 any purpose and without fee is hereby granted, provided that this
6 copyright and permission notice appear on all copies of the
7 software and supporting documentation, the name of Cisco Systems,
8 Inc. not be used in advertising or publicity pertaining to
9 distribution of the program without specific prior permission, and
10 notice be given in supporting documentation that modification,
11 copying and distribution is by permission of Cisco Systems, Inc.
13 Cisco Systems, Inc. makes no representations about the suitability
14 of this software for any purpose. THIS SOFTWARE IS PROVIDED ``AS
15 IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
16 WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS FOR A PARTICULAR PURPOSE.
21 * regcomp and regexec -- regsub and regerror are elsewhere
22 * @(#)regexp.c 1.3 of 18 April 87
24 * Copyright (c) 1986 by University of Toronto.
25 * Written by Henry Spencer. Not derived from licensed software.
27 * Permission is granted to anyone to use this software for any
28 * purpose on any computer system, and to redistribute it freely,
29 * subject to the following restrictions:
31 * 1. The author is not responsible for the consequences of use of
32 * this software, no matter how awful, even if they arise
35 * 2. The origin of this software must not be misrepresented, either
36 * by explicit claim or by omission.
38 * 3. Altered versions must be plainly marked as such, and must not
39 * be misrepresented as being the original software.
41 * Beware that some of this code is subtly aware of the way operator
42 * precedence is structured in regular expressions. Serious changes in
43 * regular-expression syntax might require a total rethink.
49 #ifdef WITH_INCLUDED_REGEX
53 #include <stdlib.h> /* malloc() can be found in <stdlib.h> OR <malloc.h> */
58 #include "tac_regexp.h"
59 #include "tac_regmagic.h"
60 #include "report.h" /* for regerror() */
64 * The "internal use only" fields in regexp.h are present to pass info from
65 * compile to execute that permits the execute phase to run lots faster on
66 * simple cases. They are:
68 * regstart char that must begin a match; '\0' if none obvious
69 * reganch is the match anchored (at beginning-of-line only)?
70 * regmust string (pointer into program) that match must include, or NULL
71 * regmlen length of regmust string
73 * Regstart and reganch permit very fast decisions on suitable starting points
74 * for a match, cutting down the work a lot. Regmust permits fast rejection
75 * of lines that cannot possibly match. The regmust tests are costly enough
76 * that regcomp() supplies a regmust only if the r.e. contains something
77 * potentially expensive (at present, the only such thing detected is * or +
78 * at the start of the r.e., which can involve a lot of backup). Regmlen is
79 * supplied because the test in regexec() needs it and regcomp() is computing
84 * Structure for regexp "program". This is essentially a linear encoding
85 * of a nondeterministic finite-state machine (aka syntax charts or
86 * "railroad normal form" in parsing technology). Each node is an opcode
87 * plus a "next" pointer, possibly plus an operand. "Next" pointers of
88 * all nodes except BRANCH implement concatenation; a "next" pointer with
89 * a BRANCH on both ends of it is connecting two alternatives. (Here we
90 * have one of the subtle syntax dependencies: an individual BRANCH (as
91 * opposed to a collection of them) is never concatenated with anything
92 * because of operator precedence.) The operand of some types of node is
93 * a literal string; for others, it is a node leading into a sub-FSM. In
94 * particular, the operand of a BRANCH node is the first node of the branch.
95 * (NB this is *not* a tree structure: the tail of the branch connects
96 * to the thing following the set of BRANCHes.) The opcodes are:
99 /* definition number opnd? meaning */
100 #define END 0 /* no End of program. */
101 #define BOL 1 /* no Match "" at beginning of line. */
102 #define EOL 2 /* no Match "" at end of line. */
103 #define ANY 3 /* no Match any one character. */
104 #define ANYOF 4 /* str Match any character in this string. */
105 #define ANYBUT 5 /* str Match any character not in this string. */
106 #define BRANCH 6 /* node Match this alternative, or the next... */
107 #define BACK 7 /* no Match "", "next" ptr points backward. */
108 #define EXACTLY 8 /* str Match this string. */
109 #define NOTHING 9 /* no Match empty string. */
110 #define STAR 10 /* node Match this (simple) thing 0 or more times. */
111 #define PLUS 11 /* node Match this (simple) thing 1 or more times. */
112 #define OPEN 20 /* no Mark this point in input as start of #n. */
113 /* OPEN+1 is number 1, etc. */
114 #define CLOSE 30 /* no Analogous to OPEN. */
119 * BRANCH The set of branches constituting a single choice are hooked
120 * together with their "next" pointers, since precedence prevents
121 * anything being concatenated to any individual branch. The
122 * "next" pointer of the last BRANCH in a choice points to the
123 * thing following the whole choice. This is also where the
124 * final "next" pointer of each individual branch points; each
125 * branch starts with the operand node of a BRANCH node.
127 * BACK Normal "next" pointers all implicitly point forward; BACK
128 * exists to make loop structures possible.
130 * STAR,PLUS '?', and complex '*' and '+', are implemented as circular
131 * BRANCH structures using BACK. Simple cases (one character
132 * per match) are implemented with STAR and PLUS for speed
133 * and to minimize recursive plunges.
135 * OPEN,CLOSE ...are numbered at compile time.
139 * A node is one char of opcode followed by two chars of "next" pointer.
140 * "Next" pointers are stored as two 8-bit pieces, high order first. The
141 * value is a positive offset from the opcode of the node containing it.
142 * An operand, if any, simply follows the node. (Note that much of the
143 * code generation knows about this implicit relationship.)
145 * Using two bytes for the "next" pointer is vast overkill for most things,
146 * but allows patterns to get big without disasters.
149 #define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
150 #define OPERAND(p) ((p) + 3)
153 * See regmagic.h for one further detail of program structure.
158 * Utility definitions.
161 #define UCHARAT(p) ((int)*(unsigned char *)(p))
163 #define UCHARAT(p) ((int)*(p)&CHARBITS)
166 #define FAIL(m) { tac_regerror(m); return(NULL); }
167 #define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
168 #define META "^$.[()|?+*\\"
171 * Flags to be passed up and down.
173 #define HASWIDTH 01 /* Known never to match null string. */
174 #define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
175 #define SPSTART 04 /* Starts with * or +. */
176 #define WORST 0 /* Worst case. */
179 * Global work variables for regcomp().
181 static const char *regparse; /* Input-scan pointer. */
182 static int regnpar; /* () count. */
183 static char regdummy;
184 static char *regcode; /* Code-emit pointer; ®dummy = don't. */
185 static long regsize; /* Code size. */
188 * Forward declarations for regcomp()'s friends.
190 static char *reg TAC_ARGS((int paren, int *flagp));
191 static char *regbranch TAC_ARGS((int *flagp));
192 static char *regpiece TAC_ARGS((int *flagp));
193 static char *regatom TAC_ARGS((int *flagp));
194 static char *regnode TAC_ARGS((int op));
195 static void regc TAC_ARGS((int b));
196 static void reginsert TAC_ARGS((int op, char *opnd));
197 static void regtail TAC_ARGS((char *p, char *val));
198 static void regoptail TAC_ARGS((char *p, char *val));
199 static int regtry TAC_ARGS((tac_regexp *prog, const char *string));
200 static int regmatch TAC_ARGS((char *prog));
201 static int regrepeat TAC_ARGS((char *p));
202 static char *regnext TAC_ARGS((register char *p));
204 static int strcspn TAC_ARGS((char *s1, char *s2));
209 - regcomp - compile a regular expression into internal code
211 * We can't allocate space until we know how big the compiled form will be,
212 * but we can't compile it (and thus know how big it is) until we've got a
213 * place to put the code. So we cheat: we compile it twice, once with code
214 * generation turned off and size counting turned on, and once "for real".
215 * This also means that we don't allocate space until we are sure that the
216 * thing really will compile successfully, and we never have to move the
217 * code and thus invalidate pointers into it. (Note that it has to be in
218 * one piece because free() must be able to free it all.)
220 * Beware that the optimization-preparation code in here knows about some
221 * of the structure of the compiled regexp.
224 tac_regexp *tac_regcomp TAC_ARGS((const char *exp));
230 register tac_regexp *r;
232 register char *longest;
237 FAIL("NULL argument");
239 /* First pass: determine size, legality. */
245 if (reg(0, &flags) == NULL)
248 /* Small enough for pointer-storage convention? */
249 if (regsize >= 32767L) /* Probably could be 65535L. */
250 FAIL("regexp too big");
252 /* Allocate space. */
253 r = (tac_regexp *)malloc(sizeof(tac_regexp) + (unsigned)regsize);
255 FAIL("out of space");
257 /* Second pass: emit code. */
260 regcode = r->program;
262 if (reg(0, &flags) == NULL)
265 /* Dig out information for optimizations. */
266 r->regstart = '\0'; /* Worst-case defaults. */
270 scan = r->program+1; /* First BRANCH. */
271 if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
272 scan = OPERAND(scan);
274 /* Starting-point info. */
275 if (OP(scan) == EXACTLY)
276 r->regstart = *OPERAND(scan);
277 else if (OP(scan) == BOL)
281 * If there's something expensive in the r.e., find the
282 * longest literal string that must appear and make it the
283 * regmust. Resolve ties in favor of later strings, since
284 * the regstart check works with the beginning of the r.e.
285 * and avoiding duplication strengthens checking. Not a
286 * strong reason, but sufficient in the absence of others.
291 for (; scan != NULL; scan = regnext(scan))
292 if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= (unsigned)len) {
293 longest = OPERAND(scan);
294 len = strlen(OPERAND(scan));
296 r->regmust = longest;
305 - reg - regular expression, i.e. main body or parenthesized thing
307 * Caller must absorb opening parenthesis.
309 * Combining parenthesis handling with the base level of regular expression
310 * is a trifle forced, but the need to tie the tails of the branches to what
311 * follows makes it hard to avoid.
314 static char *reg TAC_ARGS((int paren, int *flagp));
318 int paren; /* Parenthesized? */
323 register char *ender;
324 register int parno = 0 /* GCC paranoia */;
327 *flagp = HASWIDTH; /* Tentatively. */
329 /* Make an OPEN node, if parenthesized. */
331 if (regnpar >= NSUBEXP)
335 ret = regnode(OPEN+parno);
339 /* Pick up the branches, linking them together. */
340 br = regbranch(&flags);
344 regtail(ret, br); /* OPEN -> first. */
347 if (!(flags&HASWIDTH))
349 *flagp |= flags&SPSTART;
350 while (*regparse == '|') {
352 br = regbranch(&flags);
355 regtail(ret, br); /* BRANCH -> BRANCH. */
356 if (!(flags&HASWIDTH))
358 *flagp |= flags&SPSTART;
361 /* Make a closing node, and hook it on the end. */
362 ender = regnode((paren) ? CLOSE+parno : END);
365 /* Hook the tails of the branches to the closing node. */
366 for (br = ret; br != NULL; br = regnext(br))
367 regoptail(br, ender);
369 /* Check for proper termination. */
370 if (paren && *regparse++ != ')') {
371 FAIL("unmatched ()");
372 } else if (!paren && *regparse != '\0') {
373 if (*regparse == ')') {
374 FAIL("unmatched ()");
376 FAIL("junk on end"); /* "Can't happen". */
384 - regbranch - one alternative of an | operator
386 * Implements the concatenation operator.
389 static char *regbranch TAC_ARGS((int *flagp));
396 register char *chain;
397 register char *latest;
400 *flagp = WORST; /* Tentatively. */
402 ret = regnode(BRANCH);
404 while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
405 latest = regpiece(&flags);
408 *flagp |= flags&HASWIDTH;
409 if (chain == NULL) /* First piece. */
410 *flagp |= flags&SPSTART;
412 regtail(chain, latest);
415 if (chain == NULL) /* Loop ran zero times. */
416 (void) regnode(NOTHING);
422 - regpiece - something followed by possible [*+?]
424 * Note that the branching code sequences used for ? and the general cases
425 * of * and + are somewhat optimized: they use the same NOTHING node as
426 * both the endmarker for their branch list and the body of the last branch.
427 * It might seem that this node could be dispensed with entirely, but the
428 * endmarker role is not redundant.
431 static char *regpiece TAC_ARGS((int *flagp));
442 ret = regatom(&flags);
452 if (!(flags&HASWIDTH) && op != '?')
453 FAIL("*+ operand could be empty");
454 *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
456 if (op == '*' && (flags&SIMPLE))
457 reginsert(STAR, ret);
458 else if (op == '*') {
459 /* Emit x* as (x&|), where & means "self". */
460 reginsert(BRANCH, ret); /* Either x */
461 regoptail(ret, regnode(BACK)); /* and loop */
462 regoptail(ret, ret); /* back */
463 regtail(ret, regnode(BRANCH)); /* or */
464 regtail(ret, regnode(NOTHING)); /* null. */
465 } else if (op == '+' && (flags&SIMPLE))
466 reginsert(PLUS, ret);
467 else if (op == '+') {
468 /* Emit x+ as x(&|), where & means "self". */
469 next = regnode(BRANCH); /* Either */
471 regtail(regnode(BACK), ret); /* loop back */
472 regtail(next, regnode(BRANCH)); /* or */
473 regtail(ret, regnode(NOTHING)); /* null. */
474 } else if (op == '?') {
475 /* Emit x? as (x|) */
476 reginsert(BRANCH, ret); /* Either x */
477 regtail(ret, regnode(BRANCH)); /* or */
478 next = regnode(NOTHING); /* null. */
480 regoptail(ret, next);
483 if (ISMULT(*regparse))
490 - regatom - the lowest level
492 * Optimization: gobbles an entire sequence of ordinary characters so that
493 * it can turn them into a single node, which is smaller to store and
494 * faster to run. Backslashed characters are exceptions, each becoming a
495 * separate node; the code is simpler that way and it's not worth fixing.
498 static char *regatom TAC_ARGS((int *flagp));
507 *flagp = WORST; /* Tentatively. */
509 switch (*regparse++) {
518 *flagp |= HASWIDTH|SIMPLE;
522 register int classend;
524 if (*regparse == '^') { /* Complement of range. */
525 ret = regnode(ANYBUT);
528 ret = regnode(ANYOF);
529 if (*regparse == ']' || *regparse == '-')
531 while (*regparse != '\0' && *regparse != ']') {
532 if (*regparse == '-') {
534 if (*regparse == ']' || *regparse == '\0')
537 class = UCHARAT(regparse-2)+1;
538 classend = UCHARAT(regparse);
539 if (class > classend+1)
540 FAIL("invalid [] range");
541 for (; class <= classend; class++)
549 if (*regparse != ']')
550 FAIL("unmatched []");
552 *flagp |= HASWIDTH|SIMPLE;
556 ret = reg(1, &flags);
559 *flagp |= flags&(HASWIDTH|SPSTART);
564 FAIL("internal urp"); /* Supposed to be caught earlier. */
569 FAIL("?+* follows nothing");
572 if (*regparse == '\0')
574 ret = regnode(EXACTLY);
577 *flagp |= HASWIDTH|SIMPLE;
584 len = strcspn(regparse, META);
586 FAIL("internal disaster");
587 ender = *(regparse+len);
588 if (len > 1 && ISMULT(ender))
589 len--; /* Back off clear of ?+* operand. */
593 ret = regnode(EXACTLY);
607 - regnode - emit a node
610 static char *regnode TAC_ARGS((int op));
612 static char * /* Location. */
614 int op; /* promoted "char" type */
620 if (ret == ®dummy) {
627 *ptr++ = '\0'; /* Null "next" pointer. */
635 - regc - emit (if appropriate) a byte of code
638 static void regc TAC_ARGS((int b));
642 int b; /* promoted "char" type */
644 if (regcode != ®dummy)
651 - reginsert - insert an operator in front of already-emitted operand
653 * Means relocating the operand.
656 static void reginsert TAC_ARGS((int op, char *opnd));
660 int op; /* promoted "char" type */
665 register char *place;
667 if (regcode == ®dummy) {
678 place = opnd; /* Op node, where operand used to be. */
685 - regtail - set the next-pointer at the end of a node chain
688 static void regtail TAC_ARGS((char *p, char *val));
702 /* Find last node. */
705 temp = regnext(scan);
711 if (OP(scan) == BACK)
715 *(scan+1) = (offset>>8)&0377;
716 *(scan+2) = offset&0377;
720 - regoptail - regtail on operand of first argument; nop if operandless
723 static void regoptail TAC_ARGS((char *p, char *val));
730 /* "Operandless" and "op != BRANCH" are synonymous in practice. */
731 if (p == NULL || p == ®dummy || OP(p) != BRANCH)
733 regtail(OPERAND(p), val);
737 * regexec and friends
741 * Global work variables for regexec().
743 static const char *reginput; /* String-input pointer. */
744 static const char *regbol; /* Beginning of input, for ^ check. */
745 static const char **regstartp; /* Pointer to startp array. */
746 static const char **regendp; /* Ditto for endp. */
751 static char *regprop TAC_ARGS((char *op));
752 static void regdump TAC_ARGS((tac_regexp *r));
756 - regexec - match a regexp against a string
759 int tac_regexec TAC_ARGS((register tac_regexp *prog, register const char *string));
762 tac_regexec(prog, string)
763 register tac_regexp *prog;
764 register const char *string;
766 register const char *s;
769 if (prog == NULL || string == NULL) {
770 tac_regerror("NULL parameter");
774 /* Check validity of program. */
775 if (UCHARAT(prog->program) != MAGIC) {
776 tac_regerror("corrupted program");
780 /* If there is a "must appear" string, look for it. */
781 if (prog->regmust != NULL) {
783 while ((s = strchr(s, prog->regmust[0])) != NULL) {
784 if (strncmp(s, prog->regmust, prog->regmlen) == 0)
785 break; /* Found it. */
788 if (s == NULL) /* Not present. */
792 /* Mark beginning of line for ^ . */
795 /* Simplest case: anchored match need be tried only once. */
797 return(regtry(prog, string));
799 /* Messy cases: unanchored match. */
801 if (prog->regstart != '\0')
802 /* We know what char it must start with. */
803 while ((s = strchr(s, prog->regstart)) != NULL) {
809 /* We don't -- general case. */
813 } while (*s++ != '\0');
820 - regtry - try match at specific point
823 static int regtry TAC_ARGS((tac_regexp *prog, const char *string));
825 static int /* 0 failure, 1 success */
831 register const char **sp;
832 register const char **ep;
835 regstartp = prog->startp;
836 regendp = prog->endp;
840 for (i = NSUBEXP; i > 0; i--) {
844 if (regmatch(prog->program + 1)) {
845 prog->startp[0] = string;
846 prog->endp[0] = reginput;
853 - regmatch - main matching routine
855 * Conceptually the strategy is simple: check to see whether the current
856 * node matches, call self recursively to see whether the rest matches,
857 * and then act accordingly. In practice we make some effort to avoid
858 * recursion, in particular by going through "ordinary" nodes (that don't
859 * need to know whether the rest of the match failed) by a loop instead of
863 static int regmatch TAC_ARGS((char *prog));
865 static int /* 0 failure, 1 success */
869 register char *scan; /* Current node. */
870 char *next; /* Next node. */
874 if (scan != NULL && regnarrate)
875 fprintf(stderr, "%s(\n", regprop(scan));
877 while (scan != NULL) {
880 fprintf(stderr, "%s...\n", regprop(scan));
882 next = regnext(scan);
886 if (reginput != regbol)
890 if (*reginput != '\0')
894 if (*reginput == '\0')
902 opnd = OPERAND(scan);
903 /* Inline the first character, for speed. */
904 if (*opnd != *reginput)
907 if (len > 1 && strncmp(opnd, reginput, len) != 0)
913 if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
918 if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
936 register const char *save;
938 no = OP(scan) - OPEN;
941 if (regmatch(next)) {
943 * Don't set startp if some later
944 * invocation of the same parentheses
947 if (regstartp[no] == NULL)
948 regstartp[no] = save;
964 register const char *save;
966 no = OP(scan) - CLOSE;
969 if (regmatch(next)) {
971 * Don't set endp if some later
972 * invocation of the same parentheses
975 if (regendp[no] == NULL)
983 register const char *save;
985 if (OP(next) != BRANCH) /* No choice. */
986 next = OPERAND(scan); /* Avoid recursion. */
990 if (regmatch(OPERAND(scan)))
993 scan = regnext(scan);
994 } while (scan != NULL && OP(scan) == BRANCH);
1002 register char nextch;
1004 register const char *save;
1008 * Lookahead to avoid useless match attempts
1009 * when we know what character comes next.
1012 if (OP(next) == EXACTLY)
1013 nextch = *OPERAND(next);
1014 min = (OP(scan) == STAR) ? 0 : 1;
1016 no = regrepeat(OPERAND(scan));
1018 /* If it could work, try it. */
1019 if (nextch == '\0' || *reginput == nextch)
1022 /* Couldn't or didn't -- back up. */
1024 reginput = save + no;
1030 return(1); /* Success! */
1033 tac_regerror("memory corruption");
1042 * We get here only if there's trouble -- normally "case END" is
1043 * the terminating point.
1045 tac_regerror("corrupted pointers");
1050 - regrepeat - repeatedly match something simple, report how many
1053 static int regrepeat TAC_ARGS((char *p));
1059 register int count = 0;
1060 register const char *scan;
1061 register char *opnd;
1067 count = strlen(scan);
1071 while (*opnd == *scan) {
1077 while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
1083 while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
1088 default: /* Oh dear. Called inappropriately. */
1089 tac_regerror("internal foulup");
1090 count = 0; /* Best compromise. */
1099 - regnext - dig the "next" pointer out of a node
1102 static char *regnext TAC_ARGS((register char *p));
1108 register int offset;
1126 - regdump - dump a regexp onto stdout in vaguely comprehensible form
1129 static void regdump TAC_ARGS((tac_regexp *r));
1136 register char op = EXACTLY; /* Arbitrary non-END op. */
1137 register char *next;
1141 while (op != END) { /* While that wasn't END last time... */
1143 printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
1145 if (next == NULL) /* Next ptr. */
1148 printf("(%d)", (s-r->program)+(next-s));
1150 if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
1151 /* Literal string, where present. */
1152 while (*s != '\0') {
1161 /* Header fields of interest. */
1162 if (r->regstart != '\0')
1163 printf("start `%c' ", r->regstart);
1165 printf("anchored ");
1166 if (r->regmust != NULL)
1167 printf("must have \"%s\"", r->regmust);
1172 - regprop - printable representation of opcode
1175 static char *regprop TAC_ARGS((char *op));
1182 static char buf[50];
1184 (void) strcpy(buf, ":");
1226 sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
1238 sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
1248 tac_regerror("corrupted opcode");
1252 (void) strcat(buf, p);
1258 * The following is provided for those people who do not have strcspn() in
1259 * their C libraries. They should get off their butts and do something
1260 * about it; at least one public-domain implementation of those (highly
1261 * useful) string routines has been published on Usenet.
1263 #ifndef HAVE_STRCSPN
1265 * strcspn - find length of initial segment of s1 consisting entirely
1266 * of characters not from s2
1269 static int strcspn TAC_ARGS((char *s1, char *s2));
1276 register char *scan1;
1277 register char *scan2;
1281 for (scan1 = s1; *scan1 != '\0'; scan1++) {
1282 for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
1283 if (*scan1 == *scan2++)
1289 #endif /* HAVE_STRCSPN */
1291 #else /* WITH_INCLUDED_REGEX */
1293 TAC_SOURCEFILE_EMPTY
1295 #endif /* WITH_INCLUDED_REGEX */