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))

Reply via email to