1 /*************************************************
2 * Perl-Compatible Regular Expressions *
3 *************************************************/
6 This is a library of functions to support regular expressions whose syntax
7 and semantics are as close as possible to those of the Perl 5 language. See
8 the file Tech.Notes for some information on the internals.
10 Written by: Philip Hazel <ph10@cam.ac.uk>
12 Copyright (c) 1997-2001 University of Cambridge
14 -----------------------------------------------------------------------------
15 Permission is granted to anyone to use this software for any purpose on any
16 computer system, and to redistribute it freely, subject to the following
19 1. This software is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 2. The origin of this software must not be misrepresented, either by
24 explicit claim or by omission.
26 3. Altered versions must be plainly marked as such, and must not be
27 misrepresented as being the original software.
29 4. If PCRE is embedded in any software that is released under the GNU
30 General Purpose Licence (GPL), then the terms of that licence shall
31 supersede any condition above with which it is incompatible.
32 -----------------------------------------------------------------------------
36 /* Include the internals header, which itself includes Standard C headers plus
37 the external pcre header. */
43 /*************************************************
44 * Set a bit and maybe its alternate case *
45 *************************************************/
47 /* Given a character, set its bit in the table, and also the bit for the other
48 version of a letter if we are caseless.
51 start_bits points to the bit map
53 caseless the caseless flag
54 cd the block with char table pointers
60 set_bit(uschar *start_bits, int c, BOOL caseless, compile_data *cd)
62 start_bits[c/8] |= (1 << (c&7));
63 if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
64 start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7));
69 /*************************************************
70 * Create bitmap of starting chars *
71 *************************************************/
73 /* This function scans a compiled unanchored expression and attempts to build a
74 bitmap of the set of initial characters. If it can't, it returns FALSE. As time
75 goes by, we may be able to get more clever at doing this.
78 code points to an expression
79 start_bits points to a 32-byte table, initialized to 0
80 caseless the current state of the caseless flag
81 cd the block with char table pointers
83 Returns: TRUE if table built, FALSE otherwise
87 set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
92 /* This next statement and the later reference to dummy are here in order to
93 trick the optimizer of the IBM C compiler for OS/2 into generating correct
94 code. Apparently IBM isn't going to fix the problem, and we would rather not
95 disable optimization (in this module it actually makes a big difference, and
96 the pcre module can use all the optimization it can get). */
102 const uschar *tcode = code + 3;
103 BOOL try_next = TRUE;
107 /* If a branch starts with a bracket or a positive lookahead assertion,
108 recurse to set bits from within them. That's all for this branch. */
110 if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT)
112 if (!set_start_bits(tcode, start_bits, caseless, cd))
122 /* Skip over extended extraction bracket number */
128 /* Skip over lookbehind and negative lookahead assertions */
132 case OP_ASSERTBACK_NOT:
133 do tcode += (tcode[1] << 8) + tcode[2]; while (*tcode == OP_ALT);
137 /* Skip over an option setting, changing the caseless flag */
140 caseless = (tcode[1] & PCRE_CASELESS) != 0;
144 /* BRAZERO does the bracket, but carries on. */
148 if (!set_start_bits(++tcode, start_bits, caseless, cd))
151 do tcode += (tcode[1] << 8) + tcode[2]; while (*tcode == OP_ALT);
155 /* Single-char * or ? sets the bit and tries the next item */
161 set_bit(start_bits, tcode[1], caseless, cd);
165 /* Single-char upto sets the bit and tries the next */
169 set_bit(start_bits, tcode[3], caseless, cd);
173 /* At least one single char sets the bit and stops */
175 case OP_EXACT: /* Fall through */
178 case OP_CHARS: /* Fall through */
183 set_bit(start_bits, tcode[1], caseless, cd);
187 /* Single character type sets the bits and stops */
190 for (c = 0; c < 32; c++)
191 start_bits[c] |= ~cd->cbits[c+cbit_digit];
196 for (c = 0; c < 32; c++)
197 start_bits[c] |= cd->cbits[c+cbit_digit];
201 case OP_NOT_WHITESPACE:
202 for (c = 0; c < 32; c++)
203 start_bits[c] |= ~cd->cbits[c+cbit_space];
208 for (c = 0; c < 32; c++)
209 start_bits[c] |= cd->cbits[c+cbit_space];
213 case OP_NOT_WORDCHAR:
214 for (c = 0; c < 32; c++)
215 start_bits[c] |= ~cd->cbits[c+cbit_word];
220 for (c = 0; c < 32; c++)
221 start_bits[c] |= cd->cbits[c+cbit_word];
225 /* One or more character type fudges the pointer and restarts, knowing
226 it will hit a single character type and stop there. */
237 /* Zero or more repeats of character types set the bits and then
242 tcode += 2; /* Fall through */
247 case OP_TYPEMINQUERY:
251 for (c = 0; c < 32; c++)
252 start_bits[c] |= ~cd->cbits[c+cbit_digit];
256 for (c = 0; c < 32; c++)
257 start_bits[c] |= cd->cbits[c+cbit_digit];
260 case OP_NOT_WHITESPACE:
261 for (c = 0; c < 32; c++)
262 start_bits[c] |= ~cd->cbits[c+cbit_space];
266 for (c = 0; c < 32; c++)
267 start_bits[c] |= cd->cbits[c+cbit_space];
270 case OP_NOT_WORDCHAR:
271 for (c = 0; c < 32; c++)
272 start_bits[c] |= ~cd->cbits[c+cbit_word];
276 for (c = 0; c < 32; c++)
277 start_bits[c] |= cd->cbits[c+cbit_word];
284 /* Character class: set the bits and either carry on or not,
285 according to the repeat count. */
290 for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
303 if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5;
304 else try_next = FALSE;
312 break; /* End of class handling */
314 } /* End of switch */
315 } /* End of try_next loop */
317 code += (code[1] << 8) + code[2]; /* Advance to next branch */
319 while (*code == OP_ALT);
325 /*************************************************
326 * Study a compiled expression *
327 *************************************************/
329 /* This function is handed a compiled expression that it must study to produce
330 information that will speed up the matching. It returns a pcre_extra block
331 which then gets handed back to pcre_exec().
334 re points to the compiled expression
335 options contains option bits
336 errorptr points to where to place error messages;
337 set NULL unless error
339 Returns: pointer to a pcre_extra block,
340 NULL on error or if no optimization possible
344 pcre_study(const pcre *external_re, int options, const char **errorptr)
346 uschar start_bits[32];
347 real_pcre_extra *extra;
348 const real_pcre *re = (const real_pcre *)external_re;
349 compile_data compile_block;
353 if (re == NULL || re->magic_number != MAGIC_NUMBER)
355 *errorptr = "argument is not a compiled regular expression";
359 if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
361 *errorptr = "unknown or incorrect option bit(s) set";
365 /* For an anchored pattern, or an unchored pattern that has a first char, or a
366 multiline pattern that matches only at "line starts", no further processing at
369 if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0)
372 /* Set the character tables in the block which is passed around */
374 compile_block.lcc = re->tables + lcc_offset;
375 compile_block.fcc = re->tables + fcc_offset;
376 compile_block.cbits = re->tables + cbits_offset;
377 compile_block.ctypes = re->tables + ctypes_offset;
379 /* See if we can find a fixed set of initial characters for the pattern. */
381 memset(start_bits, 0, 32 * sizeof(uschar));
382 if (!set_start_bits(re->code, start_bits, (re->options & PCRE_CASELESS) != 0,
383 &compile_block)) return NULL;
385 /* Get an "extra" block and put the information therein. */
387 extra = (real_pcre_extra *)(pcre_malloc)(sizeof(real_pcre_extra));
391 *errorptr = "failed to get memory";
395 extra->options = PCRE_STUDY_MAPPED;
396 memcpy(extra->start_bits, start_bits, sizeof(start_bits));
398 return (pcre_extra *)extra;