/[pcre]/code/tags/pcre-3.7/pcreposix.c
ViewVC logotype

Contents of /code/tags/pcre-3.7/pcreposix.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations) (download)
Sat Feb 24 21:38:41 2007 UTC (7 years, 8 months ago) by nigel
Original Path: code/trunk/pcreposix.c
File MIME type: text/plain
File size: 7831 byte(s)
Load pcre-2.00 into code/trunk.

1 /*************************************************
2 * Perl-Compatible Regular Expressions *
3 *************************************************/
4
5 /*
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.
9
10 This module is a wrapper that provides a POSIX API to the underlying PCRE
11 functions.
12
13 Written by: Philip Hazel <ph10@cam.ac.uk>
14
15 Copyright (c) 1998 University of Cambridge
16
17 -----------------------------------------------------------------------------
18 Permission is granted to anyone to use this software for any purpose on any
19 computer system, and to redistribute it freely, subject to the following
20 restrictions:
21
22 1. This software is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
25
26 2. The origin of this software must not be misrepresented, either by
27 explicit claim or by omission.
28
29 3. Altered versions must be plainly marked as such, and must not be
30 misrepresented as being the original software.
31 -----------------------------------------------------------------------------
32 */
33
34 #include "internal.h"
35 #include "pcreposix.h"
36 #include "stdlib.h"
37
38
39
40 /* Corresponding tables of PCRE error messages and POSIX error codes. */
41
42 static const char *estring[] = {
43 ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10,
44 ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20,
45 ERR21, ERR22, ERR23, ERR24, ERR25 };
46
47 static int eint[] = {
48 REG_EESCAPE, /* "\\ at end of pattern" */
49 REG_EESCAPE, /* "\\c at end of pattern" */
50 REG_EESCAPE, /* "unrecognized character follows \\" */
51 REG_BADBR, /* "numbers out of order in {} quantifier" */
52 REG_BADBR, /* "number too big in {} quantifier" */
53 REG_EBRACK, /* "missing terminating ] for character class" */
54 REG_ECTYPE, /* "invalid escape sequence in character class" */
55 REG_ERANGE, /* "range out of order in character class" */
56 REG_BADRPT, /* "nothing to repeat" */
57 REG_BADRPT, /* "operand of unlimited repeat could match the empty string" */
58 REG_ASSERT, /* "internal error: unexpected repeat" */
59 REG_BADPAT, /* "unrecognized character after (?" */
60 REG_ESIZE, /* "too many capturing parenthesized sub-patterns" */
61 REG_EPAREN, /* "missing )" */
62 REG_ESUBREG, /* "back reference to non-existent subpattern" */
63 REG_INVARG, /* "erroffset passed as NULL" */
64 REG_INVARG, /* "unknown option bit(s) set" */
65 REG_EPAREN, /* "missing ) after comment" */
66 REG_ESIZE, /* "too many sets of parentheses" */
67 REG_ESIZE, /* "regular expression too large" */
68 REG_ESPACE, /* "failed to get memory" */
69 REG_EPAREN, /* "unmatched brackets" */
70 REG_ASSERT, /* "internal error: code overflow" */
71 REG_BADPAT, /* "unrecognized character after (?<" */
72 REG_BADPAT, /* "lookbehind assertion is not fixed length" */
73 REG_BADPAT, /* "malformed number after (?(" */
74 REG_BADPAT, /* "conditional group containe more than two branches" */
75 REG_BADPAT /* "assertion expected after (?(" */
76 };
77
78 /* Table of texts corresponding to POSIX error codes */
79
80 static const char *pstring[] = {
81 "", /* Dummy for value 0 */
82 "internal error", /* REG_ASSERT */
83 "invalid repeat counts in {}", /* BADBR */
84 "pattern error", /* BADPAT */
85 "? * + invalid", /* BADRPT */
86 "unbalanced {}", /* EBRACE */
87 "unbalanced []", /* EBRACK */
88 "collation error - not relevant", /* ECOLLATE */
89 "bad class", /* ECTYPE */
90 "bad escape sequence", /* EESCAPE */
91 "empty expression", /* EMPTY */
92 "unbalanced ()", /* EPAREN */
93 "bad range inside []", /* ERANGE */
94 "expression too big", /* ESIZE */
95 "failed to get memory", /* ESPACE */
96 "bad back reference", /* ESUBREG */
97 "bad argument", /* INVARG */
98 "match failed" /* NOMATCH */
99 };
100
101
102
103
104 /*************************************************
105 * Translate PCRE text code to int *
106 *************************************************/
107
108 /* PCRE compile-time errors are given as strings defined as macros. We can just
109 look them up in a table to turn them into POSIX-style error codes. */
110
111 static int
112 pcre_posix_error_code(const char *s)
113 {
114 size_t i;
115 for (i = 0; i < sizeof(estring)/sizeof(char *); i++)
116 if (strcmp(s, estring[i]) == 0) return eint[i];
117 return REG_ASSERT;
118 }
119
120
121
122 /*************************************************
123 * Translate error code to string *
124 *************************************************/
125
126 size_t
127 regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
128 {
129 const char *message, *addmessage;
130 size_t length, addlength;
131
132 message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))?
133 "unknown error code" : pstring[errcode];
134 length = strlen(message) + 1;
135
136 addmessage = " at offset ";
137 addlength = (preg != NULL && (int)preg->re_erroffset != -1)?
138 strlen(addmessage) + 6 : 0;
139
140 if (errbuf_size > 0)
141 {
142 if (addlength > 0 && errbuf_size >= length + addlength)
143 sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset);
144 else
145 {
146 strncpy(errbuf, message, errbuf_size - 1);
147 errbuf[errbuf_size-1] = 0;
148 }
149 }
150
151 return length + addlength;
152 }
153
154
155
156
157 /*************************************************
158 * Free store held by a regex *
159 *************************************************/
160
161 void
162 regfree(regex_t *preg)
163 {
164 (pcre_free)(preg->re_pcre);
165 }
166
167
168
169
170 /*************************************************
171 * Compile a regular expression *
172 *************************************************/
173
174 /*
175 Arguments:
176 preg points to a structure for recording the compiled expression
177 pattern the pattern to compile
178 cflags compilation flags
179
180 Returns: 0 on success
181 various non-zero codes on failure
182 */
183
184 int
185 regcomp(regex_t *preg, const char *pattern, int cflags)
186 {
187 const char *errorptr;
188 int erroffset;
189 int options = 0;
190
191 if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS;
192 if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE;
193
194 preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset);
195 preg->re_erroffset = erroffset;
196
197 if (preg->re_pcre == NULL) return pcre_posix_error_code(errorptr);
198
199 preg->re_nsub = pcre_info(preg->re_pcre, NULL, NULL);
200 return 0;
201 }
202
203
204
205
206 /*************************************************
207 * Match a regular expression *
208 *************************************************/
209
210 int
211 regexec(regex_t *preg, const char *string, size_t nmatch,
212 regmatch_t pmatch[], int eflags)
213 {
214 int rc;
215 int options = 0;
216
217 if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
218 if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
219
220 preg->re_erroffset = (size_t)(-1); /* Only has meaning after compile */
221
222 rc = pcre_exec(preg->re_pcre, NULL, string, (int)strlen(string), options,
223 (int *)pmatch, nmatch * 2);
224
225 if (rc == 0) return 0; /* All pmatch were filled in */
226
227 if (rc > 0)
228 {
229 size_t i;
230 for (i = rc; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
231 return 0;
232 }
233
234 else switch(rc)
235 {
236 case PCRE_ERROR_NOMATCH: return REG_NOMATCH;
237 case PCRE_ERROR_NULL: return REG_INVARG;
238 case PCRE_ERROR_BADOPTION: return REG_INVARG;
239 case PCRE_ERROR_BADMAGIC: return REG_INVARG;
240 case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;
241 case PCRE_ERROR_NOMEMORY: return REG_ESPACE;
242 default: return REG_ASSERT;
243 }
244 }
245
246 /* End of pcreposix.c */

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12