The NORMAL case code in next() is needlessly complicated. The switch
statement in particular is about as creative as it can possibly be.
Isolate the early-return cases (end-of-string, bracket) from the
could-be-a-range cases (backslash, any other character).
Slightly less optimized, far simpler to read.
While here, use an ANSI function definition.
ok?
Index: str.c
===================================================================
RCS file: /cvs/src/usr.bin/tr/str.c,v
retrieving revision 1.14
diff -u -p -r1.14 str.c
--- str.c 2 Nov 2021 03:09:15 -0000 1.14
+++ str.c 2 Nov 2021 03:32:38 -0000
@@ -52,33 +52,25 @@ static int genrange(STR *);
static void genseq(STR *);
int
-next(s)
- STR *s;
+next(STR *s)
{
- int ch;
-
switch (s->state) {
case EOS:
return (0);
case INFINITE:
return (1);
case NORMAL:
- switch (ch = *s->str) {
- case '\0':
+ if (*s->str == '\0') {
s->state = EOS;
return (0);
- case '\\':
- s->lastch = backslash(s);
- break;
- case '[':
- if (bracket(s))
- return (next(s));
- /* FALLTHROUGH */
- default:
- ++s->str;
- s->lastch = ch;
- break;
}
+ if (*s->str == '[' && bracket(s))
+ return next(s);
+
+ if (*s->str == '\\')
+ s->lastch = backslash(s);
+ else
+ s->lastch = *s->str++;
/* We can start a range at any time. */
if (s->str[0] == '-' && genrange(s))