]>
Commit | Line | Data |
---|---|---|
82d76604 EA |
1 | /* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. | |
3 | Contributed by Ulrich Drepper <[email protected]>, 1996. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Library General Public License as | |
7 | published by the Free Software Foundation; either version 2 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Library General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Library General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If not, | |
17 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
18 | Boston, MA 02111-1307, USA. */ | |
f3a93606 EA |
19 | |
20 | #ifndef _REGEXP_H | |
82d76604 EA |
21 | #define _REGEXP_H 1 |
22 | ||
23 | /* The contents of this header file was first standardized in X/Open | |
24 | System Interface and Headers Issue 2, originally coming from SysV. | |
25 | In issue 4, version 2, it is marked as TO BE WITDRAWN. | |
26 | ||
27 | This code shouldn't be used in any newly written code. It is | |
28 | included only for compatibility reasons. Use the POSIX definition | |
29 | in <regex.h> for portable applications and a reasonable interface. */ | |
30 | ||
31 | #include <features.h> | |
32 | #include <alloca.h> | |
33 | #include <regex.h> | |
34 | #include <stdlib.h> | |
35 | #include <string.h> | |
36 | ||
37 | /* The implementation provided here emulates the needed functionality | |
38 | by mapping to the POSIX regular expression matcher. The interface | |
39 | for the here included function is weird (this really is a harmless | |
40 | word). | |
41 | ||
42 | The user has to provide six macros before this header file can be | |
43 | included: | |
44 | ||
45 | INIT Declarations vor variables which can be used by the | |
46 | other macros. | |
47 | ||
48 | GETC() Return the value of the next character in the regular | |
49 | expression pattern. Successive calls should return | |
50 | successive characters. | |
51 | ||
52 | PEEKC() Return the value of the next character in the regular | |
53 | expression pattern. Immediately successive calls to | |
54 | PEEKC() should return the same character which should | |
55 | also be the next character returned by GETC(). | |
56 | ||
57 | UNGETC(c) Cause `c' to be returned by the next call to GETC() and | |
58 | PEEKC(). | |
59 | ||
60 | RETURN(ptr) Used for normal exit of the `compile' function. `ptr' | |
61 | is a pointer to the character after the last character of | |
62 | the compiled regular expression. | |
63 | ||
64 | ERROR(val) Used for abnormal return from `compile'. `val' is the | |
65 | error number. The error codes are: | |
66 | 11 Range endpoint too large. | |
67 | 16 Bad number. | |
68 | 25 \digit out of range. | |
69 | 36 Illegal or missing delimiter. | |
70 | 41 No remembered search string. | |
71 | 42 \( \) imbalance. | |
72 | 43 Too many \(. | |
73 | 44 More tan two numbers given in \{ \}. | |
74 | 45 } expected after \. | |
75 | 46 First number exceeds second in \{ \}. | |
76 | 49 [ ] imbalance. | |
77 | 50 Regular expression overflow. | |
78 | ||
79 | */ | |
80 | ||
81 | __BEGIN_DECLS | |
82 | ||
83 | /* Interface variables. They contain the results of the successful | |
84 | calls to `setp' and `advance'. */ | |
85 | extern char *loc1; | |
86 | extern char *loc2; | |
87 | ||
88 | /* The use of this variable in the `advance' function is not | |
89 | supported. */ | |
90 | extern char *locs; | |
91 | ||
f3a93606 | 92 | |
82d76604 EA |
93 | #ifndef __DO_NOT_DEFINE_COMPILE |
94 | /* Get and compile the user supplied pattern up to end of line or | |
95 | string or until EOF is seen, whatever happens first. The result is | |
96 | placed in the buffer starting at EXPBUF and delimited by ENDBUF. | |
97 | ||
98 | This function cannot be defined in the libc itself since it depends | |
99 | on the macros. */ | |
f3a93606 | 100 | char * |
82d76604 EA |
101 | compile (char *__restrict instring, char *__restrict expbuf, |
102 | __const char *__restrict endbuf, int eof) | |
f3a93606 | 103 | { |
82d76604 EA |
104 | char *__input_buffer = NULL; |
105 | size_t __input_size = 0; | |
106 | size_t __current_size = 0; | |
107 | int __ch; | |
108 | int __error; | |
109 | INIT | |
110 | ||
111 | /* Align the expression buffer according to the needs for an object | |
112 | of type `regex_t'. Then check for minimum size of the buffer for | |
113 | the compiled regular expression. */ | |
114 | regex_t *__expr_ptr; | |
115 | # if defined __GNUC__ && __GNUC__ >= 2 | |
116 | const size_t __req = __alignof__ (regex_t *); | |
117 | # else | |
118 | /* How shall we find out? We simply guess it and can change it is | |
119 | this really proofs to be wrong. */ | |
120 | const size_t __req = 8; | |
121 | # endif | |
122 | expbuf += __req; | |
123 | expbuf -= (expbuf - ((char *) 0)) % __req; | |
124 | if (endbuf < expbuf + sizeof (regex_t)) | |
125 | { | |
126 | ERROR (50); | |
127 | } | |
128 | __expr_ptr = (regex_t *) expbuf; | |
129 | /* The remaining space in the buffer can be used for the compiled | |
130 | pattern. */ | |
131 | __expr_ptr->buffer = expbuf + sizeof (regex_t); | |
132 | __expr_ptr->allocated = endbuf - (char *) __expr_ptr->buffer; | |
133 | ||
134 | while ((__ch = (GETC ())) != eof) | |
135 | { | |
136 | if (__ch == '\0' || __ch == '\n') | |
137 | { | |
138 | UNGETC (__ch); | |
139 | break; | |
f3a93606 | 140 | } |
f3a93606 | 141 | |
82d76604 EA |
142 | if (__current_size + 1 >= __input_size) |
143 | { | |
144 | size_t __new_size = __input_size ? 2 * __input_size : 128; | |
145 | char *__new_room = (char *) alloca (__new_size); | |
146 | /* See whether we can use the old buffer. */ | |
147 | if (__new_room + __new_size == __input_buffer) | |
148 | { | |
149 | __input_size += __new_size; | |
150 | __input_buffer = (char *) memcpy (__new_room, __input_buffer, | |
151 | __current_size); | |
152 | } | |
153 | else if (__input_buffer + __input_size == __new_room) | |
154 | __input_size += __new_size; | |
155 | else | |
156 | { | |
157 | __input_size = __new_size; | |
158 | __input_buffer = (char *) memcpy (__new_room, __input_buffer, | |
159 | __current_size); | |
160 | } | |
f3a93606 | 161 | } |
82d76604 EA |
162 | __input_buffer[__current_size++] = __ch; |
163 | } | |
164 | __input_buffer[__current_size++] = '\0'; | |
f3a93606 | 165 | |
82d76604 EA |
166 | /* Now compile the pattern. */ |
167 | __error = regcomp (__expr_ptr, __input_buffer, REG_NEWLINE); | |
168 | if (__error != 0) | |
169 | /* Oh well, we have to translate POSIX error codes. */ | |
170 | switch (__error) | |
171 | { | |
172 | case REG_BADPAT: | |
173 | case REG_ECOLLATE: | |
174 | case REG_ECTYPE: | |
175 | case REG_EESCAPE: | |
176 | case REG_BADRPT: | |
177 | case REG_EEND: | |
178 | case REG_ERPAREN: | |
179 | default: | |
180 | /* There is no matching error code. */ | |
181 | RETURN (36); | |
182 | case REG_ESUBREG: | |
183 | RETURN (25); | |
184 | case REG_EBRACK: | |
185 | RETURN (49); | |
186 | case REG_EPAREN: | |
187 | RETURN (42); | |
188 | case REG_EBRACE: | |
189 | RETURN (44); | |
190 | case REG_BADBR: | |
191 | RETURN (46); | |
192 | case REG_ERANGE: | |
193 | RETURN (11); | |
194 | case REG_ESPACE: | |
195 | case REG_ESIZE: | |
196 | ERROR (50); | |
197 | } | |
198 | ||
199 | /* Everything is ok. */ | |
200 | RETURN ((char *) (__expr_ptr->buffer + __expr_ptr->used)); | |
f3a93606 | 201 | } |
82d76604 EA |
202 | #endif |
203 | ||
204 | ||
205 | /* Find the next match in STRING. The compiled regular expression is | |
206 | found in the buffer starting at EXPBUF. `loc1' will return the | |
207 | first character matched and `loc2' points to the next unmatched | |
208 | character. */ | |
209 | extern int step __P ((__const char *__restrict __string, | |
210 | __const char *__restrict __expbuf)); | |
211 | ||
212 | /* Match the beginning of STRING with the compiled regular expression | |
213 | in EXPBUF. If the match is successful `loc2' will contain the | |
214 | position of the first unmatched character. */ | |
215 | extern int advance __P ((__const char *__restrict __string, | |
216 | __const char *__restrict __expbuf)); | |
217 | ||
218 | ||
219 | __END_DECLS | |
f3a93606 | 220 | |
82d76604 | 221 | #endif /* regexp.h */ |