* Copyright (c) 1991 The Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)str.c 5.9 (Berkeley) 3/4/93";
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
= strstr(s
->str
+ 2, ":]")) == NULL
)
case '=': /* "[=equiv=]" */
if ((p
= strstr(s
->str
+ 2, "=]")) == NULL
)
default: /* "[\###*n]" or "[#*n]" */
if ((p
= strpbrk(s
->str
+ 2, "*]")) == NULL
)
if (p
[0] != '*' || index(p
, ']') == NULL
)
static int isblank(x
) /* until 4.4 */
if ((x
== ' ') || (x
== '\t')) return 1;
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 */