* Copyright (c) 1991 The Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)str.c 5.3 (Berkeley) %G%";
static int backslash
__P((STR
*));
static int bracket
__P((STR
*));
static int c_class
__P((const void *, const void *));
static void genclass
__P((STR
*));
static void genequiv
__P((STR
*));
static int genrange
__P((STR
*));
static void genseq
__P((STR
*));
s
->lastch
= backslash(s
);
/* We can start a range at any time. */
if (s
->str
[0] == '-' && genrange(s
))
if ((s
->lastch
= s
->set
[s
->cnt
++]) == OOBCH
) {
case ':': /* "[:class:]" */
if ((p
= strpbrk(s
->str
+ 1, ":]")) == NULL
)
if (p
[0] != ':' || p
[1] != ']')
case '=': /* "[=equiv=]" */
if ((p
= strpbrk(s
->str
+ 1, "=]")) == NULL
)
if (p
[0] != '=' || p
[1] != ']')
default: /* "[\###*]" or "[#*]" */
if ((p
= strpbrk(s
->str
+ 1, "*]")) == NULL
)
if (p
[0] != '*' || index(p
, ']') == NULL
)
static CLASS classes
[] = {
register int cnt
, (*func
) __P((int));
if ((cp
= (CLASS
*)bsearch(&tmp
, classes
, sizeof(classes
) /
sizeof(CLASS
), sizeof(CLASS
), c_class
)) == NULL
)
err("unknown class %s", s
->str
);
if ((cp
->set
= p
= malloc((NCHARS
+ 1) * sizeof(int))) == NULL
)
err("%s", strerror(errno
));
bzero(p
, (NCHARS
+ 1) * sizeof(int));
for (cnt
= 0, func
= cp
->func
; cnt
< NCHARS
; ++cnt
)
return (strcmp(((CLASS
*)a
)->name
, ((CLASS
*)b
)->name
));
* English doesn't have any equivalence classes, so for now
* we just syntax check and grab the character.
s
->equiv
[0] = backslash(s
);
err("misplaced equivalence equals sign");
err("misplaced equivalence equals sign");
stopval
= *++s
->str
== '\\' ? backslash(s
) : *s
->str
;
if (stopval
< s
->lastch
) {
s
->cnt
= stopval
- s
->lastch
+ 1;
err("sequences only valid in string2");
s
->lastch
= backslash(s
);
err("misplaced sequence asterisk");
s
->cnt
= strtol(s
->str
, &ep
, 0);
err("illegal sequence count");
s
->state
= s
->cnt
? SEQUENCE
: INFINITE
;
/* Use the #defines isXXX() here, DON'T use them above. */
* Translate \??? into a character. Up to 3 octal digits, if no digits either
* an escape code or a literal character.
register int ch
, cnt
, val
;
if (!isascii(ch
) || !isdigit(ch
))
val
= val
* 8 + ch
- '0';
case 'a': /* escape characters */