1 |
/* dfa.c - deterministic extended regexp routines for GNU |
/* dfa.c - deterministic extended regexp routines for GNU |
2 |
Copyright 1988, 1998, 2000 Free Software Foundation, Inc. |
Copyright 1988, 1998, 2000, 2002, 2004 Free Software Foundation, Inc. |
3 |
|
|
4 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
5 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
26 |
#include <ctype.h> |
#include <ctype.h> |
27 |
#include <stdio.h> |
#include <stdio.h> |
28 |
|
|
29 |
|
#ifndef VMS |
30 |
#include <sys/types.h> |
#include <sys/types.h> |
31 |
|
#else |
32 |
|
#include <stddef.h> |
33 |
|
#endif |
34 |
#ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
35 |
#include <stdlib.h> |
#include <stdlib.h> |
36 |
#else |
#else |
48 |
# include <locale.h> |
# include <locale.h> |
49 |
#endif |
#endif |
50 |
|
|
51 |
#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC |
#include "mbsupport.h" /* defined MBS_SUPPORT if appropriate */ |
|
/* We can handle multibyte string. */ |
|
|
# define MBS_SUPPORT |
|
|
#endif |
|
52 |
|
|
53 |
#ifdef MBS_SUPPORT |
#ifdef MBS_SUPPORT |
54 |
# include <wchar.h> |
# include <wchar.h> |
55 |
# include <wctype.h> |
# include <wctype.h> |
56 |
#endif |
#endif |
57 |
|
|
58 |
|
|
59 |
#ifndef DEBUG /* use the same approach as regex.c */ |
#ifndef DEBUG /* use the same approach as regex.c */ |
60 |
#undef assert |
#undef assert |
61 |
#define assert(e) |
#define assert(e) |
101 |
host does not conform to Posix. */ |
host does not conform to Posix. */ |
102 |
#define ISASCIIDIGIT(c) ((unsigned) (c) - '0' <= 9) |
#define ISASCIIDIGIT(c) ((unsigned) (c) - '0' <= 9) |
103 |
|
|
104 |
|
/* Don't use gettext if ENABLE_NLS is not defined */ |
105 |
/* If we (don't) have I18N. */ |
/* If we (don't) have I18N. */ |
106 |
/* glibc defines _ */ |
/* glibc defines _ */ |
107 |
#ifndef _ |
#ifdef ENABLE_NLS |
108 |
# ifdef HAVE_LIBINTL_H |
# ifndef _ |
109 |
# include <libintl.h> |
# ifdef HAVE_LIBINTL_H |
110 |
# ifndef _ |
# include <libintl.h> |
111 |
# define _(Str) gettext (Str) |
# ifndef _ |
112 |
|
# define _(Str) gettext (Str) |
113 |
|
# endif |
114 |
# endif |
# endif |
|
# else |
|
|
# define _(Str) (Str) |
|
115 |
# endif |
# endif |
116 |
#endif |
#endif |
117 |
|
#ifndef _ |
118 |
|
# define _(Str) (Str) |
119 |
|
#endif |
120 |
|
|
121 |
#include "regex.h" |
#include "regex.h" |
122 |
#include "dfa.h" |
#include "dfa.h" |
131 |
#endif |
#endif |
132 |
|
|
133 |
static void dfamust PARAMS ((struct dfa *dfa)); |
static void dfamust PARAMS ((struct dfa *dfa)); |
134 |
|
|
135 |
|
static ptr_t xcalloc PARAMS ((size_t n, size_t s)); |
136 |
|
static ptr_t xmalloc PARAMS ((size_t n)); |
137 |
|
static ptr_t xrealloc PARAMS ((ptr_t p, size_t n)); |
138 |
|
#ifdef DEBUG |
139 |
|
static void prtok PARAMS ((token t)); |
140 |
|
#endif |
141 |
|
static int tstbit PARAMS ((unsigned b, charclass c)); |
142 |
|
static void setbit PARAMS ((unsigned b, charclass c)); |
143 |
|
static void clrbit PARAMS ((unsigned b, charclass c)); |
144 |
|
static void copyset PARAMS ((charclass src, charclass dst)); |
145 |
|
static void zeroset PARAMS ((charclass s)); |
146 |
|
static void notset PARAMS ((charclass s)); |
147 |
|
static int equal PARAMS ((charclass s1, charclass s2)); |
148 |
|
static int charclass_index PARAMS ((charclass s)); |
149 |
|
static int looking_at PARAMS ((const char *s)); |
150 |
|
static token lex PARAMS ((void)); |
151 |
|
static void addtok PARAMS ((token t)); |
152 |
|
static void atom PARAMS ((void)); |
153 |
|
static int nsubtoks PARAMS ((int tindex)); |
154 |
|
static void copytoks PARAMS ((int tindex, int ntokens)); |
155 |
|
static void closure PARAMS ((void)); |
156 |
|
static void branch PARAMS ((void)); |
157 |
static void regexp PARAMS ((int toplevel)); |
static void regexp PARAMS ((int toplevel)); |
158 |
|
static void copy PARAMS ((position_set const *src, position_set *dst)); |
159 |
|
static void insert PARAMS ((position p, position_set *s)); |
160 |
|
static void merge PARAMS ((position_set const *s1, position_set const *s2, position_set *m)); |
161 |
|
static void delete PARAMS ((position p, position_set *s)); |
162 |
|
static int state_index PARAMS ((struct dfa *d, position_set const *s, |
163 |
|
int newline, int letter)); |
164 |
|
static void build_state PARAMS ((int s, struct dfa *d)); |
165 |
|
static void build_state_zero PARAMS ((struct dfa *d)); |
166 |
|
static char *icatalloc PARAMS ((char *old, char *new)); |
167 |
|
static char *icpyalloc PARAMS ((char *string)); |
168 |
|
static char *istrstr PARAMS ((char *lookin, char *lookfor)); |
169 |
|
static void ifree PARAMS ((char *cp)); |
170 |
|
static void freelist PARAMS ((char **cpp)); |
171 |
|
static char **enlist PARAMS ((char **cpp, char *new, size_t len)); |
172 |
|
static char **comsubs PARAMS ((char *left, char *right)); |
173 |
|
static char **addlists PARAMS ((char **old, char **new)); |
174 |
|
static char **inboth PARAMS ((char **left, char **right)); |
175 |
|
|
176 |
static ptr_t |
static ptr_t |
177 |
xcalloc (size_t n, size_t s) |
xcalloc (size_t n, size_t s) |
390 |
... |
... |
391 |
nth byte : cur_mb_index = n */ |
nth byte : cur_mb_index = n */ |
392 |
static unsigned char *mblen_buf;/* Correspond to the input buffer in dfaexec(). |
static unsigned char *mblen_buf;/* Correspond to the input buffer in dfaexec(). |
393 |
Each element store the amount of remain |
Each element store the amount of remain |
394 |
byte of corresponding multibyte character |
byte of corresponding multibyte character |
395 |
in the input string. A element's value |
in the input string. A element's value |
396 |
is 0 if corresponding character is a |
is 0 if corresponding character is a |
397 |
singlebyte chracter. |
singlebyte chracter. |
398 |
e.g. input : 'a', <mb(0)>, <mb(1)>, <mb(2)> |
e.g. input : 'a', <mb(0)>, <mb(1)>, <mb(2)> |
399 |
mblen_buf : 0, 3, 2, 1 |
mblen_buf : 0, 3, 2, 1 |
400 |
*/ |
*/ |
401 |
static wchar_t *inputwcs; /* Wide character representation of input |
static wchar_t *inputwcs; /* Wide character representation of input |
402 |
string in dfaexec(). |
string in dfaexec(). |
403 |
The length of this array is same as |
The length of this array is same as |
405 |
inputstring[i] is a single-byte char, |
inputstring[i] is a single-byte char, |
406 |
or 1st byte of a multibyte char. |
or 1st byte of a multibyte char. |
407 |
And inputwcs[i] is the codepoint. */ |
And inputwcs[i] is the codepoint. */ |
408 |
static unsigned char const *buf_begin;/* reference to begin in dfaexec(). */ |
static unsigned char const *buf_begin; /* reference to begin in dfaexec(). */ |
409 |
static unsigned char const *buf_end; /* reference to end in dfaexec(). */ |
static unsigned char const *buf_end; /* reference to end in dfaexec(). */ |
410 |
static unsigned long buf_offset; /* Go fast. */ |
static unsigned long buf_offset; /* Go fast. */ |
411 |
#endif /* MBS_SUPPORT */ |
#endif /* MBS_SUPPORT */ |
500 |
#endif /* MBS_SUPPORT */ |
#endif /* MBS_SUPPORT */ |
501 |
|
|
502 |
#ifdef MBS_SUPPORT |
#ifdef MBS_SUPPORT |
503 |
/* Multibyte character handling sub-routin for lex. |
/* Multibyte character handling sub-routine for lex. |
504 |
This function parse a bracket expression and build a struct |
This function parse a bracket expression and build a struct |
505 |
mb_char_classes. */ |
mb_char_classes. */ |
506 |
static void |
static void |
516 |
REALLOC_IF_NECESSARY(dfa->mbcsets, struct mb_char_classes, |
REALLOC_IF_NECESSARY(dfa->mbcsets, struct mb_char_classes, |
517 |
dfa->mbcsets_alloc, dfa->nmbcsets + 1); |
dfa->mbcsets_alloc, dfa->nmbcsets + 1); |
518 |
/* dfa->multibyte_prop[] hold the index of dfa->mbcsets. |
/* dfa->multibyte_prop[] hold the index of dfa->mbcsets. |
519 |
We will update dfa->multibyte_prop in addtok(), because we can't |
We will update dfa->multibyte_prop[] in addtok(), because we can't |
520 |
decide the index in dfa->tokens[]. */ |
decide the index in dfa->tokens[]. */ |
521 |
|
|
522 |
/* Initialize work are */ |
/* Initialize work are */ |
2362 |
} |
} |
2363 |
|
|
2364 |
#ifdef MBS_SUPPORT |
#ifdef MBS_SUPPORT |
2365 |
/* Multibyte character handling sub-routins for dfaexec. */ |
/* Multibyte character handling sub-routines for dfaexec. */ |
2366 |
|
|
2367 |
/* Initial state may encounter the byte which is not a singlebyte character |
/* Initial state may encounter the byte which is not a singlebyte character |
2368 |
nor 1st byte of a multibyte character. But it is incorrect for initial |
nor 1st byte of a multibyte character. But it is incorrect for initial |
2932 |
SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p); |
SKIP_REMAINS_MB_IF_INITIAL_STATE(s, p); |
2933 |
if (d->states[s].mbps.nelem != 0) |
if (d->states[s].mbps.nelem != 0) |
2934 |
{ |
{ |
2935 |
/* Can match with a multibyte character( and multi |
/* Can match with a multibyte character (and multi |
2936 |
character collating element). */ |
character collating element). */ |
2937 |
unsigned char const *nextp; |
unsigned char const *nextp; |
2938 |
nextp = p; |
nextp = p; |