str.c (0da30e9aa76c5df66cd092f30b904824b0594ccc) str.c (af647767ed8f2ec38251e8185ef0b6adb35529e6)
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35#if 0
35static char sccsid[] = "@(#)str.c 8.2 (Berkeley) 4/28/95";
36static char sccsid[] = "@(#)str.c 8.2 (Berkeley) 4/28/95";
37#endif
38static const char rcsid[] =
39 "$Id$";
36#endif /* not lint */
37
38#include <sys/cdefs.h>
39#include <sys/types.h>
40
40#endif /* not lint */
41
42#include <sys/cdefs.h>
43#include <sys/types.h>
44
41#include <errno.h>
45#include <ctype.h>
46#include <err.h>
42#include <stddef.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46
47#include "extern.h"
48
49static int backslash __P((STR *));

--- 11 unchanged lines hidden (view full) ---

61 register int ch;
62
63 switch (s->state) {
64 case EOS:
65 return (0);
66 case INFINITE:
67 return (1);
68 case NORMAL:
47#include <stddef.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51
52#include "extern.h"
53
54static int backslash __P((STR *));

--- 11 unchanged lines hidden (view full) ---

66 register int ch;
67
68 switch (s->state) {
69 case EOS:
70 return (0);
71 case INFINITE:
72 return (1);
73 case NORMAL:
69 switch (ch = *s->str) {
74 switch (ch = (u_char)*s->str) {
70 case '\0':
71 s->state = EOS;
72 return (0);
73 case '\\':
74 s->lastch = backslash(s);
75 break;
76 case '[':
77 if (bracket(s))

--- 60 unchanged lines hidden (view full) ---

138 return (0);
139 s->str += 1;
140 genseq(s);
141 return (1);
142 }
143 /* NOTREACHED */
144}
145
75 case '\0':
76 s->state = EOS;
77 return (0);
78 case '\\':
79 s->lastch = backslash(s);
80 break;
81 case '[':
82 if (bracket(s))

--- 60 unchanged lines hidden (view full) ---

143 return (0);
144 s->str += 1;
145 genseq(s);
146 return (1);
147 }
148 /* NOTREACHED */
149}
150
146int isalnum __P((int)),
147 isalpha __P((int)),
148 isblank __P((int)),
149 isspace __P((int)),
150 iscntrl __P((int)),
151 isdigit __P((int)),
152 isgraph __P((int)),
153 islower __P((int)),
154 isprint __P((int)),
155 ispunct __P((int)),
156 isupper __P((int)),
157 isxdigit __P((int));
158
159typedef struct {
160 char *name;
161 int (*func) __P((int));
162 int *set;
163} CLASS;
164
165static CLASS classes[] = {
151typedef struct {
152 char *name;
153 int (*func) __P((int));
154 int *set;
155} CLASS;
156
157static CLASS classes[] = {
158#undef isalnum
166 { "alnum", isalnum, },
159 { "alnum", isalnum, },
160#undef isalpha
167 { "alpha", isalpha, },
161 { "alpha", isalpha, },
162#undef isblank
168 { "blank", isblank, },
163 { "blank", isblank, },
164#undef iscntrl
169 { "cntrl", iscntrl, },
165 { "cntrl", iscntrl, },
166#undef isdigit
170 { "digit", isdigit, },
167 { "digit", isdigit, },
168#undef isgraph
171 { "graph", isgraph, },
169 { "graph", isgraph, },
170#undef islower
172 { "lower", islower, },
171 { "lower", islower, },
173 { "print", isupper, },
172#undef isprint
173 { "print", isprint, },
174#undef ispunct
174 { "punct", ispunct, },
175 { "punct", ispunct, },
176#undef isspace
175 { "space", isspace, },
177 { "space", isspace, },
178#undef isupper
176 { "upper", isupper, },
179 { "upper", isupper, },
180#undef isxdigit
177 { "xdigit", isxdigit, },
178};
179
180static void
181genclass(s)
182 STR *s;
183{
184 register int cnt, (*func) __P((int));
185 CLASS *cp, tmp;
186 int *p;
187
188 tmp.name = s->str;
189 if ((cp = (CLASS *)bsearch(&tmp, classes, sizeof(classes) /
190 sizeof(CLASS), sizeof(CLASS), c_class)) == NULL)
181 { "xdigit", isxdigit, },
182};
183
184static void
185genclass(s)
186 STR *s;
187{
188 register int cnt, (*func) __P((int));
189 CLASS *cp, tmp;
190 int *p;
191
192 tmp.name = s->str;
193 if ((cp = (CLASS *)bsearch(&tmp, classes, sizeof(classes) /
194 sizeof(CLASS), sizeof(CLASS), c_class)) == NULL)
191 err("unknown class %s", s->str);
195 errx(1, "unknown class %s", s->str);
192
193 if ((cp->set = p = malloc((NCHARS + 1) * sizeof(int))) == NULL)
196
197 if ((cp->set = p = malloc((NCHARS + 1) * sizeof(int))) == NULL)
194 err("%s", strerror(errno));
198 errx(1, "malloc");
195 bzero(p, (NCHARS + 1) * sizeof(int));
196 for (cnt = 0, func = cp->func; cnt < NCHARS; ++cnt)
197 if ((func)(cnt))
198 *p++ = cnt;
199 *p = OOBCH;
200
201 s->cnt = 0;
202 s->state = SET;

--- 13 unchanged lines hidden (view full) ---

216 */
217static void
218genequiv(s)
219 STR *s;
220{
221 if (*s->str == '\\') {
222 s->equiv[0] = backslash(s);
223 if (*s->str != '=')
199 bzero(p, (NCHARS + 1) * sizeof(int));
200 for (cnt = 0, func = cp->func; cnt < NCHARS; ++cnt)
201 if ((func)(cnt))
202 *p++ = cnt;
203 *p = OOBCH;
204
205 s->cnt = 0;
206 s->state = SET;

--- 13 unchanged lines hidden (view full) ---

220 */
221static void
222genequiv(s)
223 STR *s;
224{
225 if (*s->str == '\\') {
226 s->equiv[0] = backslash(s);
227 if (*s->str != '=')
224 err("misplaced equivalence equals sign");
228 errx(1, "misplaced equivalence equals sign");
225 } else {
226 s->equiv[0] = s->str[0];
227 if (s->str[1] != '=')
229 } else {
230 s->equiv[0] = s->str[0];
231 if (s->str[1] != '=')
228 err("misplaced equivalence equals sign");
232 errx(1, "misplaced equivalence equals sign");
229 }
230 s->str += 2;
231 s->cnt = 0;
232 s->state = SET;
233 s->set = s->equiv;
234}
235
236static int
237genrange(s)
238 STR *s;
239{
240 int stopval;
241 char *savestart;
242
243 savestart = s->str;
233 }
234 s->str += 2;
235 s->cnt = 0;
236 s->state = SET;
237 s->set = s->equiv;
238}
239
240static int
241genrange(s)
242 STR *s;
243{
244 int stopval;
245 char *savestart;
246
247 savestart = s->str;
244 stopval = *++s->str == '\\' ? backslash(s) : *s->str++;
248 stopval = *++s->str == '\\' ? backslash(s) : (u_char)*s->str++;
245 if (stopval < (u_char)s->lastch) {
246 s->str = savestart;
247 return (0);
248 }
249 s->cnt = stopval - s->lastch + 1;
250 s->state = RANGE;
251 --s->lastch;
252 return (1);
253}
254
255static void
256genseq(s)
257 STR *s;
258{
259 char *ep;
260
261 if (s->which == STRING1)
249 if (stopval < (u_char)s->lastch) {
250 s->str = savestart;
251 return (0);
252 }
253 s->cnt = stopval - s->lastch + 1;
254 s->state = RANGE;
255 --s->lastch;
256 return (1);
257}
258
259static void
260genseq(s)
261 STR *s;
262{
263 char *ep;
264
265 if (s->which == STRING1)
262 err("sequences only valid in string2");
266 errx(1, "sequences only valid in string2");
263
264 if (*s->str == '\\')
265 s->lastch = backslash(s);
266 else
267 s->lastch = *s->str++;
268 if (*s->str != '*')
267
268 if (*s->str == '\\')
269 s->lastch = backslash(s);
270 else
271 s->lastch = *s->str++;
272 if (*s->str != '*')
269 err("misplaced sequence asterisk");
273 errx(1, "misplaced sequence asterisk");
270
271 switch (*++s->str) {
272 case '\\':
273 s->cnt = backslash(s);
274 break;
275 case ']':
276 s->cnt = 0;
277 ++s->str;
278 break;
279 default:
274
275 switch (*++s->str) {
276 case '\\':
277 s->cnt = backslash(s);
278 break;
279 case ']':
280 s->cnt = 0;
281 ++s->str;
282 break;
283 default:
280 if (isdigit(*s->str)) {
284 if (isdigit((u_char)*s->str)) {
281 s->cnt = strtol(s->str, &ep, 0);
282 if (*ep == ']') {
283 s->str = ep + 1;
284 break;
285 }
286 }
285 s->cnt = strtol(s->str, &ep, 0);
286 if (*ep == ']') {
287 s->str = ep + 1;
288 break;
289 }
290 }
287 err("illegal sequence count");
291 errx(1, "illegal sequence count");
288 /* NOTREACHED */
289 }
290
291 s->state = s->cnt ? SEQUENCE : INFINITE;
292}
293
292 /* NOTREACHED */
293 }
294
295 s->state = s->cnt ? SEQUENCE : INFINITE;
296}
297
294/* Use the #defines isXXX() here, DON'T use them above. */
295#include <ctype.h>
296
297/*
298 * Translate \??? into a character. Up to 3 octal digits, if no digits either
299 * an escape code or a literal character.
300 */
301static int
302backslash(s)
303 register STR *s;
304{
305 register int ch, cnt, val;
306
307 for (cnt = val = 0;;) {
298/*
299 * Translate \??? into a character. Up to 3 octal digits, if no digits either
300 * an escape code or a literal character.
301 */
302static int
303backslash(s)
304 register STR *s;
305{
306 register int ch, cnt, val;
307
308 for (cnt = val = 0;;) {
308 ch = *++s->str;
309 ch = (u_char)*++s->str;
309 if (!isascii(ch) || !isdigit(ch))
310 break;
311 val = val * 8 + ch - '0';
312 if (++cnt == 3) {
313 ++s->str;
314 break;
315 }
316 }

--- 26 unchanged lines hidden ---
310 if (!isascii(ch) || !isdigit(ch))
311 break;
312 val = val * 8 + ch - '0';
313 if (++cnt == 3) {
314 ++s->str;
315 break;
316 }
317 }

--- 26 unchanged lines hidden ---