about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--Etc/zsh-development-guide3
-rw-r--r--Src/Modules/curses.c4
-rw-r--r--Src/Modules/stat.c2
-rw-r--r--Src/Modules/zftp.c12
-rw-r--r--Src/Modules/zpty.c2
-rw-r--r--Src/Modules/zutil.c24
-rw-r--r--Src/Zle/compcore.c6
-rw-r--r--Src/Zle/complete.c2
-rw-r--r--Src/Zle/complist.c12
-rw-r--r--Src/Zle/zle.h2
-rw-r--r--Src/Zle/zle_keymap.c22
-rw-r--r--Src/Zle/zle_main.c4
-rw-r--r--Src/Zle/zle_thingy.c4
-rw-r--r--Src/Zle/zle_utils.c4
-rw-r--r--Src/builtin.c20
-rw-r--r--Src/exec.c2
-rw-r--r--Src/glob.c4
-rw-r--r--Src/hist.c6
-rw-r--r--Src/init.c10
-rw-r--r--Src/input.c8
-rw-r--r--Src/lex.c10
-rw-r--r--Src/math.c2
-rw-r--r--Src/module.c2
-rw-r--r--Src/params.c25
-rw-r--r--Src/parse.c6
-rw-r--r--Src/pattern.c81
-rw-r--r--Src/prompt.c2
-rw-r--r--Src/sort.c4
-rw-r--r--Src/subst.c6
-rw-r--r--Src/utils.c68
-rw-r--r--Src/zsh.h13
-rw-r--r--Src/ztype.h2
-rw-r--r--configure.ac10
34 files changed, 192 insertions, 204 deletions
diff --git a/ChangeLog b/ChangeLog
index e9e572957..996704135 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2022-12-16  Oliver Kiddle  <opk@zsh.org>
 
+	* 51212: Etc/zsh-development-guide, Src/Modules/curses.c,
+	Src/Modules/stat.c, Src/Modules/zftp.c, Src/Modules/zpty.c,
+	Src/Modules/zutil.c, Src/Zle/compcore.c, Src/Zle/complete.c,
+	Src/Zle/complist.c, Src/Zle/zle.h, Src/Zle/zle_keymap.c,
+	Src/Zle/zle_main.c, Src/Zle/zle_thingy.c, Src/Zle/zle_utils.c,
+	Src/builtin.c, Src/exec.c, Src/glob.c, Src/hist.c, Src/init.c,
+	Src/input.c, Src/lex.c, Src/math.c, Src/module.c, Src/params.c,
+	Src/parse.c, Src/pattern.c, Src/prompt.c, Src/sort.c, Src/subst.c,
+	Src/utils.c, Src/zsh.h, Src/ztype.h, configure.ac: remove STOUC()
+	macro which served as a workaround for ancient compilers where
+	casts to unsigned char were broken
+
 	* 51215: Src/Zle/zle_keymap.c, Test/X03zlebindkey.ztst,
 	Test/X02zlevi.ztst: consume whole CSI sequences from the input
 	even where they aren't explicitly bound
diff --git a/Etc/zsh-development-guide b/Etc/zsh-development-guide
index e8c292cfd..565b0b1d9 100644
--- a/Etc/zsh-development-guide
+++ b/Etc/zsh-development-guide
@@ -223,9 +223,6 @@ C coding style
 * Do not use space between the function name and the opening parenthesis.
   Use space after if/for/while.  Use space after type casts.
 
-* Do not use (unsigned char) casts since some compilers do not handle
-  them properly.  Use the provided STOUC(X) macro instead.
-
 * If you use emacs 19.30 or newer you can put the following line to your
   ~/.emacs file to make these formatting rules the default:
 
diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c
index e46903916..ad17ed65f 100644
--- a/Src/Modules/curses.c
+++ b/Src/Modules/curses.c
@@ -1426,10 +1426,10 @@ zccmd_querychar(const char *nam, char **args)
     inc &= A_CHARTEXT;
     if (imeta(inc)) {
 	instr[0] = Meta;
-	instr[1] = STOUC(inc ^ 32);
+	instr[1] = (unsigned char) (inc ^ 32);
 	instr[2] = '\0';
     } else {
-	instr[0] = STOUC(inc);
+  	instr[0] = (unsigned char) inc;
 	instr[1] = '\0';
     }
     attrs = inc;
diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c
index 0df9b35b7..c9f851974 100644
--- a/Src/Modules/stat.c
+++ b/Src/Modules/stat.c
@@ -406,7 +406,7 @@ bin_stat(char *name, char **args, Options ops, UNUSED(int func))
 	} else {
 	    for (; *arg; arg++) {
 		if (strchr("glLnNorstT", *arg))
-		    ops->ind[STOUC(*arg)] = 1;
+		    ops->ind[(unsigned char) *arg] = 1;
 		else if (*arg == 'A') {
 		    if (arg[1]) {
 			arrnam = arg+1;
diff --git a/Src/Modules/zftp.c b/Src/Modules/zftp.c
index e8e239e76..49b3ffa89 100644
--- a/Src/Modules/zftp.c
+++ b/Src/Modules/zftp.c
@@ -944,9 +944,9 @@ zfopendata(char *name, union tcp_sockaddr *zdsockp, int *is_passivep)
 		return 1;
 	    }
 	    for (i = 0; i < 4; i++)
-		iaddr[i] = STOUC(nums[i]);
-	    iport[0] = STOUC(nums[4]);
-	    iport[1] = STOUC(nums[5]);
+		iaddr[i] = (unsigned char) nums[i];
+	    iport[0] = (unsigned char) nums[4];
+	    iport[1] = (unsigned char) nums[5];
 
 	    memcpy(&zdsockp->in.sin_addr, iaddr, sizeof(iaddr));
 	    memcpy(&zdsockp->in.sin_port, iport, sizeof(iport));
@@ -2438,7 +2438,7 @@ zftp_type(char *name, char **args, int flags)
 	fflush(stdout);
 	return 0;
     } else {
-	nt = toupper(STOUC(*str));
+	nt = toupper((unsigned char) *str);
 	/*
 	 * RFC959 specifies other types, but these are the only
 	 * ones we know what to do with.
@@ -2472,7 +2472,7 @@ zftp_mode(char *name, char **args, UNUSED(int flags))
 	fflush(stdout);
 	return 0;
     }
-    nt = str[0] = toupper(STOUC(*str));
+    nt = str[0] = toupper((unsigned char) *str);
     if (str[1] || (nt != 'S' && nt != 'B')) {
 	zwarnnam(name, "transfer mode %s not recognised", str);
 	return 1;
@@ -3075,7 +3075,7 @@ bin_zftp(char *name, char **args, UNUSED(Options ops), UNUSED(int func))
     if ((prefs = getsparam_u("ZFTP_PREFS"))) {
 	zfprefs = 0;
 	for (ptr = prefs; *ptr; ptr++) {
-	    switch (toupper(STOUC(*ptr))) {
+	    switch (toupper((unsigned char) *ptr)) {
 	    case 'S':
 		/* sendport */
 		zfprefs |= ZFPF_SNDP;
diff --git a/Src/Modules/zpty.c b/Src/Modules/zpty.c
index dfd2a2a7a..c2656698c 100644
--- a/Src/Modules/zpty.c
+++ b/Src/Modules/zpty.c
@@ -638,7 +638,7 @@ ptyread(char *nam, Ptycmd cmd, char **args, int noblock, int mustmatch)
 		readchar = cmd->read;
 		cmd->read = -1;
 	    } else
-		readchar = STOUC(buf[used]);
+		readchar = (unsigned char) buf[used];
 	    if (imeta(readchar)) {
 		buf[used++] = Meta;
 		buf[used++] = (char) (readchar ^ 32);
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 2f17c03f1..8a7d0a4c5 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -795,11 +795,11 @@ static char *zformat_substring(char* instr, char **specs, char **outp,
 
 	    if (idigit(*s)) {
 		for (min = 0; idigit(*s); s++)
-		    min = (min * 10) + (int) STOUC(*s) - '0';
+		    min = (min * 10) + (int) (unsigned char) *s - '0';
 	    }
 
 	    /* Ternary expressions */
-	    testit = (STOUC(*s) == '(');
+	    testit = ((unsigned char) *s == '(');
 	    if (testit && s[1] == '-')
 	    {
 		/* Allow %(-1... etc. */
@@ -808,25 +808,25 @@ static char *zformat_substring(char* instr, char **specs, char **outp,
 	    }
 	    if ((*s == '.' || testit) && idigit(s[1])) {
 		for (max = 0, s++; idigit(*s); s++)
-		    max = (max * 10) + (int) STOUC(*s) - '0';
+		    max = (max * 10) + (int) (unsigned char) *s - '0';
 	    } else if (*s == '.' || testit)
 		s++;
 
-	    if (testit && STOUC(*s)) {
+	    if (testit && (unsigned char) *s) {
 		int actval, testval, endcharl;
 
 		/* Only one number is useful for ternary expressions. */
 		testval = (min >= 0) ? min : (max >= 0) ? max : 0;
 
-		if (specs[STOUC(*s)] && *specs[STOUC(*s)]) {
+		if (specs[(unsigned char) *s] && *specs[(unsigned char) *s]) {
 		    if (presence) {
 			if (testval)
 #ifdef MULTIBYTE_SUPPORT
 			    if (isset(MULTIBYTE))
-				actval = MB_METASTRWIDTH(specs[STOUC(*s)]);
+				actval = MB_METASTRWIDTH(specs[(unsigned char) *s]);
 			    else
 #endif
-				actval = strlen(specs[STOUC(*s)]);
+				actval = strlen(specs[(unsigned char) *s]);
 		        else
 			    actval = 1;
 			actval = right ? (testval < actval) : (testval >= actval);
@@ -834,7 +834,7 @@ static char *zformat_substring(char* instr, char **specs, char **outp,
 			if (right) /* put the sign back */
 			    testval *= -1;
 			/* zero means values are equal, i.e. true */
-			actval = (int)mathevali(specs[STOUC(*s)]) - testval;
+			actval = (int) mathevali(specs[(unsigned char) *s]) - testval;
 		    }
 		} else
 		    actval = presence ? !right : testval;
@@ -855,7 +855,7 @@ static char *zformat_substring(char* instr, char **specs, char **outp,
 		    return NULL;
 	    } else if (skip) {
 		continue;
-	    } else if ((spec = specs[STOUC(*s)])) {
+	    } else if ((spec = specs[(unsigned char) *s])) {
 		int len;
 
 		if ((len = strlen(spec)) > max && max >= 0)
@@ -950,7 +950,7 @@ bin_zformat(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 		    zwarnnam(nam, "invalid argument: %s", *ap);
 		    return 1;
 		}
-		specs[STOUC(ap[0][0])] = ap[0] + 2;
+		specs[(unsigned char) ap[0][0]] = ap[0] + 2;
 	    }
 	    out = (char *) zhalloc(olen = 128);
 
@@ -1864,7 +1864,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	d->vals = d->last = NULL;
 	opt_descs = d;
 	if (!o[1])
-	    sopts[STOUC(*o)] = d;
+	    sopts[(unsigned char) *o] = d;
 	if ((flags & ZOF_MAP) && !map_opt_desc(d)) {
 	    zwarnnam(nam, "cyclic option mapping: %s", args[-1]);
 	    return 1;
@@ -1888,7 +1888,7 @@ bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
 	}
 	if (!(d = lookup_opt(o + 1))) {
 	    while (*++o) {
-		if (!(d = sopts[STOUC(*o)])) {
+		if (!(d = sopts[(unsigned char) *o])) {
 		    if (fail) {
 			if (*o != '-')
 			    zwarnnam(nam, "bad option: -%c", *o);
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 4ac5d089f..64a860fa3 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -2898,9 +2898,9 @@ add_match_data(int alt, char *str, char *orig, Cline line,
 		*t++ = '$';
 		*t++ = '\'';
 		*t++ = '\\';
-		*t++ = '0' + ((STOUC(curchar) >> 6) & 7);
-		*t++ = '0' + ((STOUC(curchar) >> 3) & 7);
-		*t++ = '0' + (STOUC(curchar) & 7);
+		*t++ = '0' + (((unsigned char) curchar >> 6) & 7);
+		*t++ = '0' + (((unsigned char) curchar >> 3) & 7);
+		*t++ = '0' + ((unsigned char) curchar & 7);
 		*t++ = '\'';
 	    } while (cnt == MB_INCOMPLETE && fs < fe);
 	    /* Scanning restarts from the spot after the char we skipped. */
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 67a60963e..96ad7b3f1 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -518,7 +518,7 @@ parse_class(Cpattern p, char *iptr)
 	    ch = range_type((char *)iptr, nptr-iptr);
 	    iptr = nptr + 2;
 	    if (ch != PP_UNKWN)
-		*optr++ = STOUC(Meta) + ch;
+		*optr++ = (unsigned char) Meta + ch;
 	} else {
 	    /* characters stay metafied */
 	    char *ptr1 = iptr;
diff --git a/Src/Zle/complist.c b/Src/Zle/complist.c
index 0dc64db6a..6e0eac31f 100644
--- a/Src/Zle/complist.c
+++ b/Src/Zle/complist.c
@@ -291,12 +291,12 @@ getcolval(char *s, int multi)
 	    case '?': *p = '\177'; break;
 	    default:
 		if (*s >= '0' && *s <= '7') {
-		    int i = STOUC(*s);
+		    int i = (unsigned char) *s;
 
 		    if (*++s >= '0' && *s <= '7') {
-			i = (i * 8) + STOUC(*s);
+			i = (i * 8) + (unsigned char) *s;
 			if (*++s >= '0' && *s <= '7')
-			    i = (i * 8) + STOUC(*s);
+			    i = (i * 8) + (unsigned char) *s;
 		    }
 		    *p = (char) i;
 		} else
@@ -305,7 +305,7 @@ getcolval(char *s, int multi)
 	} else if (*s == '^') {
 	    if ((s[1] >= '@' && s[1] <= '_') ||
 		(s[1] >= 'a' && s[1] <= 'z'))
-		*p = (char) (STOUC(*s) & ~0x60);
+		*p = (char) ((unsigned char) *s & ~0x60);
 	    else if (s[1] == '?')
 		*p = '\177';
 	    else {
@@ -794,7 +794,7 @@ clnicezputs(int do_colors, char *s, int ml)
 	 */
 	for (t = sptr; *t; t++) {
 	    /* Input is metafied... */
-	    int nc = (*t == Meta) ? STOUC(*++t ^ 32) : STOUC(*t);
+	    int nc = (*t == Meta) ? (unsigned char) (*++t ^ 32) : (unsigned char) *t;
 	    /* Is the screen full? */
 	    if (ml == mlend - 1 && col == zterm_columns - 1) {
 		mlprinted = ml - oml;
@@ -852,7 +852,7 @@ clnicezputs(int do_colors, char *s, int ml)
 	    cc = *s++ ^ 32;
 
 	for (t = nicechar(cc); *t; t++) {
-	    int nc = (*t == Meta) ? STOUC(*++t ^ 32) : STOUC(*t);
+	    int nc = (*t == Meta) ? (unsigned char) (*++t ^ 32) : (unsigned char) *t;
 	    if (ml == mlend - 1 && col == zterm_columns - 1) {
 		mlprinted = ml - oml;
 		return 0;
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index f59545397..97cc7d797 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -526,7 +526,7 @@ typedef REFRESH_ELEMENT *REFRESH_STRING;
     ((int)((unsigned)(x) - ZSH_INVALID_WCHAR_BASE))
 /* Turn a single byte character into a private wide character */
 #define ZSH_CHAR_TO_INVALID_WCHAR(x)			\
-    ((wchar_t)(STOUC(x) + ZSH_INVALID_WCHAR_BASE))
+    ((wchar_t)((unsigned char) x + ZSH_INVALID_WCHAR_BASE))
 #endif
 
 
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c
index 48691e8d0..ec8dd031e 100644
--- a/Src/Zle/zle_keymap.c
+++ b/Src/Zle/zle_keymap.c
@@ -404,7 +404,7 @@ static void
 scankeys(HashNode hn, UNUSED(int flags))
 {
     Key k = (Key) hn;
-    int f = k->nam[0] == Meta ? STOUC(k->nam[1])^32 : STOUC(k->nam[0]);
+    int f = k->nam[0] == Meta ? (unsigned char) k->nam[1]^32 : (unsigned char) k->nam[0];
     char m[3];
 
     while(skm_last < f) {
@@ -566,7 +566,7 @@ mod_export int
 bindkey(Keymap km, const char *seq, Thingy bind, char *str)
 {
     Key k;
-    int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]);
+    int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0];
     char *buf, *ptr;
 
     if(km->flags & KM_IMMUTABLE)
@@ -661,7 +661,7 @@ keybind(Keymap km, char *seq, char **strp)
     Key k;
 
     if(ztrlen(seq) == 1) {
-	int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]);
+	int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0];
 	Thingy bind = km->first[f];
 
 	if(bind)
@@ -687,7 +687,7 @@ keyisprefix(Keymap km, char *seq)
     if(!*seq)
 	return 1;
     if(ztrlen(seq) == 1) {
-	int f = seq[0] == Meta ? STOUC(seq[1])^32 : STOUC(seq[0]);
+	int f = seq[0] == Meta ? (unsigned char) seq[1]^32 : (unsigned char) seq[0];
 
 	if(km->first[f])
 	    return 0;
@@ -764,10 +764,10 @@ bin_bindkey(char *name, char **argv, Options ops, UNUSED(int func))
     int n;
 
     /* select operation and ensure no clashing arguments */
-    for(op = opns; op->o && !OPT_ISSET(ops,STOUC(op->o)); op++) ;
+    for(op = opns; op->o && !OPT_ISSET(ops,(unsigned char) op->o); op++) ;
     if(op->o)
 	for(opp = op; (++opp)->o; )
-	    if(OPT_ISSET(ops,STOUC(opp->o))) {
+	    if(OPT_ISSET(ops,(unsigned char) opp->o)) {
 		zwarnnam(name, "incompatible operation selection options");
 		return 1;
 	    }
@@ -1049,7 +1049,7 @@ bin_bindkey_bind(char *name, char *kmname, Keymap km, char **argv, Options ops,
 	    char m[3];
 
 	    if(len < 2 || len > 2 + (bseq[1] == '-') ||
-	       (first = STOUC(bseq[0])) > (last = STOUC(bseq[len - 1]))) {
+	       (first = (unsigned char) bseq[0]) > (last = (unsigned char) bseq[len - 1])) {
 		zwarnnam(name, "malformed key range `%s'", useq);
 		ret = 1;
 	    } else {
@@ -1149,8 +1149,8 @@ scanbindlist(char *seq, Thingy bind, char *str, void *magic)
     if(bind == bs->bind && (bind || !strcmp(str, bs->str)) &&
        ztrlen(seq) == 1 && ztrlen(bs->lastseq) == 1) {
 	int l = bs->lastseq[1] ?
-	    STOUC(bs->lastseq[1]) ^ 32 : STOUC(bs->lastseq[0]);
-	int t = seq[1] ? STOUC(seq[1]) ^ 32 : STOUC(seq[0]);
+	    (unsigned char) bs->lastseq[1] ^ 32 : (unsigned char) bs->lastseq[0];
+	int t = seq[1] ? (unsigned char) seq[1] ^ 32 : (unsigned char) seq[0];
 
 	if(t == l + 1) {
 	    zsfree(bs->lastseq);
@@ -1526,10 +1526,10 @@ getrestchar_keybuf(void)
      */
     while (1) {
 	if (bufind < buflen) {
-	    c = STOUC(keybuf[bufind++]);
+	    c = (unsigned char) keybuf[bufind++];
 	    if (c == Meta) {
 		DPUTS(bufind == buflen, "Meta at end of keybuf");
-		c = STOUC(keybuf[bufind++]) ^ 32;
+		c = (unsigned char) keybuf[bufind++] ^ 32;
 	    }
 	} else {
 	    /*
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 9edf30e01..40b902901 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -876,7 +876,7 @@ getbyte(long do_keytmout, int *timeout, int full)
 #endif
 
     if (kungetct)
-	ret = STOUC(kungetbuf[--kungetct]);
+	ret = (unsigned char) kungetbuf[--kungetct];
     else {
 	for (;;) {
 	    int q = queue_signal_level();
@@ -940,7 +940,7 @@ getbyte(long do_keytmout, int *timeout, int full)
 	else if (cc == '\n')
 	    cc = '\r';
 
-	ret = STOUC(cc);
+	ret = (unsigned char) cc;
     }
     /*
      * curvichg.buf is raw bytes, not wide characters, so is dealt
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index cd3f2c356..1b036a8a0 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -366,10 +366,10 @@ bin_zle(char *name, char **args, Options ops, UNUSED(int func))
     int n;
 
     /* select operation and ensure no clashing arguments */
-    for(op = opns; op->o && !OPT_ISSET(ops,STOUC(op->o)); op++) ;
+    for(op = opns; op->o && !OPT_ISSET(ops, (unsigned char) op->o); op++) ;
     if(op->o)
 	for(opp = op; (++opp)->o; )
-	    if(OPT_ISSET(ops,STOUC(opp->o))) {
+	    if(OPT_ISSET(ops, (unsigned char) opp->o)) {
 		zwarnnam(name, "incompatible operation selection options");
 		return 1;
 	    }
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 3d9017dcf..2536e9faa 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -1265,7 +1265,7 @@ bindztrdup(char *str)
     char *buf, *ptr, *ret;
 
     for(ptr = str; *ptr; ptr++) {
-	c = *ptr == Meta ? STOUC(*++ptr) ^ 32 : STOUC(*ptr);
+	c = *ptr == Meta ? (unsigned char) *++ptr ^ 32 : (unsigned char) *ptr;
 	if(c & 0x80) {
 	    len += 3;
 	    c &= 0x7f;
@@ -1279,7 +1279,7 @@ bindztrdup(char *str)
     }
     ptr = buf = zalloc(len);
     for(; *str; str++) {
-	c = *str == Meta ? STOUC(*++str) ^ 32 : STOUC(*str);
+	c = *str == Meta ? (unsigned char) *++str ^ 32 : (unsigned char) *str;
 	if(c & 0x80) {
 	    *ptr++ = '\\';
 	    *ptr++ = 'M';
diff --git a/Src/builtin.c b/Src/builtin.c
index a7b7755a7..db83313d6 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2634,7 +2634,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
      * these flags are defined in zsh.h         */
     for (; *optstr; optstr++, bit <<= 1)
     {
-	int optval = STOUC(*optstr);
+	int optval = (unsigned char) *optstr;
 	if (OPT_MINUS(ops,optval))
 	    on |= bit;
 	else if (OPT_PLUS(ops,optval))
@@ -4752,7 +4752,7 @@ bin_print(char *name, char **args, Options ops, int func)
 		     */
 		    if (*aptr == '\033' || *aptr == '\233') {
 			for (aptr++, l--;
-			     l && !isalpha(STOUC(*aptr));
+			     l && !isalpha((unsigned char) (*aptr));
 			     aptr++, l--)
 			    ;
 			aptr++;
@@ -5313,9 +5313,9 @@ bin_print(char *name, char **args, Options ops, int func)
 		    else
 			cc = WEOF;
 		    if (cc == WEOF)
-			cc = (curlen > 1) ? STOUC(curarg[1]) : 0;
+			cc = (curlen > 1) ? (unsigned char) (curarg[1]) : 0;
 #else
-		    cc = (curlen > 1) ? STOUC(curarg[1]) : 0;
+		    cc = (curlen > 1) ? (unsigned char) (curarg[1]) : 0;
 #endif
 		    if (type == 2) {
 			doubleval = cc;
@@ -6685,7 +6685,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 		    continue;
 		first = 0;
 	    }
-	    if (imeta(STOUC(*bptr))) {
+	    if (imeta((unsigned char) *bptr)) {
 		bptr[1] = bptr[0] ^ 32;
 		bptr[0] = Meta;
 		bptr += 2;
@@ -6878,7 +6878,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func))
 		if (bslash)
 		    continue;
 	    }
-	    if (imeta(STOUC(*bptr))) {
+	    if (imeta((unsigned char) *bptr)) {
 		bptr[1] = bptr[0] ^ 32;
 		bptr[0] = Meta;
 		bptr += 2;
@@ -7000,14 +7000,14 @@ zread(int izle, int *readchar, long izle_timeout)
 	   buffer.  This may be a null byte to indicate EOF.  If reading from the
 	   buffer, move on the buffer pointer. */
 	if (*zbuf == Meta)
-	    return zbuf++, STOUC(*zbuf++ ^ 32);
+	    return zbuf++, (unsigned char) (*zbuf++ ^ 32);
 	else
-	    return (*zbuf) ? STOUC(*zbuf++) : EOF;
+	    return (*zbuf) ? (unsigned char) *zbuf++ : EOF;
     }
     if (*readchar >= 0) {
 	cc = *readchar;
 	*readchar = -1;
-	return STOUC(cc);
+	return (unsigned char) cc;
     }
     for (;;) {
 	/* read a character from readfd */
@@ -7015,7 +7015,7 @@ zread(int izle, int *readchar, long izle_timeout)
 	switch (ret) {
 	case 1:
 	    /* return the character read */
-	    return STOUC(cc);
+	    return (unsigned char) cc;
 	case -1:
 #if defined(EAGAIN) || defined(EWOULDBLOCK)
 	    if (!retry && readfd == 0 && (
diff --git a/Src/exec.c b/Src/exec.c
index 2b7e0c7c5..c8eb71b34 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -603,7 +603,7 @@ zexecve(char *pth, char **argv, char **newenvp)
                         isbinary = 1;
                         hasletter = 0;
                         for (ptr = execvebuf; ptr < ptr2; ptr++) {
-                            if (islower(STOUC(*ptr)) || *ptr == '$' || *ptr == '`')
+			    if (islower((unsigned char) *ptr) || *ptr == '$' || *ptr == '`')
                                 hasletter = 1;
                             if (hasletter && *ptr == '\n') {
                                 isbinary = 0;
diff --git a/Src/glob.c b/Src/glob.c
index 490bafc37..63f8a5fa7 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -2418,11 +2418,11 @@ xpandbraces(LinkList list, LinkNode *np)
 	memset(ccl, 0, sizeof(ccl) / sizeof(ccl[0]));
 	for (p = str + 1; p < str2;) {
 	    if (itok(c1 = *p++))
-		c1 = ztokens[c1 - STOUC(Pound)];
+		c1 = ztokens[c1 - (unsigned char) Pound];
 	    if ((char) c1 == Meta)
 		c1 = 32 ^ *p++;
 	    if (itok(c2 = *p))
-		c2 = ztokens[c2 - STOUC(Pound)];
+		c2 = ztokens[c2 - (unsigned char) Pound];
 	    if ((char) c2 == Meta)
 		c2 = 32 ^ p[1];
 	    if (IS_DASH((char)c1) && lastch >= 0 &&
diff --git a/Src/hist.c b/Src/hist.c
index bff0abe61..82d03a840 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -2235,7 +2235,7 @@ casemodify(char *str, int how)
 		char *mbptr;
 
 		for (mbptr = mbstr; mbptr < mbstr + len2; mbptr++) {
-		    if (imeta(STOUC(*mbptr))) {
+		    if (imeta((unsigned char) *mbptr)) {
 			*ptr2++ = Meta;
 			*ptr2++ = *mbptr ^ 32;
 		    } else
@@ -2254,10 +2254,10 @@ casemodify(char *str, int how)
 	    int c;
 	    int mod = 0;
 	    if (*str == Meta) {
-		c = STOUC(str[1] ^ 32);
+		c = (unsigned char) (str[1] ^ 32);
 		str += 2;
 	    } else
-		c = STOUC(*str++);
+		c = (unsigned char) *str++;
 	    switch (how) {
 	    case CASMOD_LOWER:
 		if (isupper(c)) {
diff --git a/Src/init.c b/Src/init.c
index 871d46b12..9981d059a 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -500,10 +500,10 @@ parseopts(char *nam, char ***argvp, char *new_opts, char **cmdp,
 		    }
 		}
               break;
-	    } else if (isspace(STOUC(**argv))) {
+	    } else if (isspace((unsigned char) **argv)) {
 		/* zsh's typtab not yet set, have to use ctype */
 		while (*++*argv)
-		    if (!isspace(STOUC(**argv))) {
+		    if (!isspace((unsigned char) **argv)) {
 		     badoptionstring:
 			WARN_OPTION("bad option string: '%s'", args);
 			return 1;
@@ -1724,9 +1724,9 @@ zsh_main(UNUSED(int argc), char **argv)
      * interactive
      */
     typtab['\0'] |= IMETA;
-    typtab[STOUC(Meta)  ] |= IMETA;
-    typtab[STOUC(Marker)] |= IMETA;
-    for (t0 = (int)STOUC(Pound); t0 <= (int)STOUC(Nularg); t0++)
+    typtab[(unsigned char) Meta  ] |= IMETA;
+    typtab[(unsigned char) Marker] |= IMETA;
+    for (t0 = (int) (unsigned char) Pound; t0 <= (int) (unsigned char) Nularg; t0++)
 	typtab[t0] |= ITOK | IMETA;
 
     for (t = argv; *t; *t = metafy(*t, -1, META_ALLOC), t++);
diff --git a/Src/input.c b/Src/input.c
index 9898a7177..d55b05696 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -220,7 +220,7 @@ shingetchar(void)
     int nread, rsize = isset(SHINSTDIN) ? 1 : SHINBUFSIZE;
 
     if (shinbufptr < shinbufendptr)
-	return STOUC(*shinbufptr++);
+	return (unsigned char) *shinbufptr++;
 
     shinbufreset();
 #ifdef USE_LSEEK
@@ -242,7 +242,7 @@ shingetchar(void)
 		zerr("lseek(%d, %d): %e", SHIN, -(nread - rsize), errno);
 	} else
 	    shinbufendptr = shinbuffer + nread;
-	return STOUC(*shinbufptr++);
+	return (unsigned char) *shinbufptr++;
     }
 #endif
     for (;;) {
@@ -259,7 +259,7 @@ shingetchar(void)
     }
     if (shinbufendptr == shinbuffer)
         return -1;
-    return STOUC(*shinbufptr++);
+    return (unsigned char) *shinbufptr++;
 }
 
 /* Read a line from SHIN.  Convert tokens and   *
@@ -328,7 +328,7 @@ ingetc(void)
 	if (inbufleft) {
 	    inbufleft--;
 	    inbufct--;
-	    if (itok(lastc = STOUC(*inbufptr++)))
+	    if (itok(lastc = (unsigned char) *inbufptr++))
 		continue;
 	    if (((inbufflags & INP_LINENO) || !strin) && lastc == '\n')
 		lineno++;
diff --git a/Src/lex.c b/Src/lex.c
index e2f8bcfb1..15da85a93 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -423,7 +423,7 @@ initlextabs(void)
     for (t0 = 0; lx2[t0]; t0++)
 	lexact2[(int)lx2[t0]] = t0;
     lexact2['&'] = LX2_BREAK;
-    lexact2[STOUC(Meta)] = LX2_META;
+    lexact2[(unsigned char) Meta] = LX2_META;
     lextok2['*'] = Star;
     lextok2['?'] = Quest;
     lextok2['{'] = Inbrace;
@@ -722,7 +722,7 @@ gettok(void)
 	}
 	return peek;
     }
-    switch (lexact1[STOUC(c)]) {
+    switch (lexact1[(unsigned char) c]) {
     case LX1_BKSLASH:
 	d = hgetc();
 	if (d == '\n')
@@ -960,8 +960,8 @@ gettokstr(int c, int sub)
 	if (inbl && !in_brace_param && !pct)
 	    act = LX2_BREAK;
 	else {
-	    act = lexact2[STOUC(c)];
-	    c = lextok2[STOUC(c)];
+	    act = lexact2[(unsigned char) c];
+	    c = lextok2[(unsigned char) c];
 	}
 	switch (act) {
 	case LX2_BREAK:
@@ -1263,7 +1263,7 @@ gettokstr(int c, int sub)
 		    continue;
 	    } else {
 		add(Bnull);
-		if (c == STOUC(Meta)) {
+		if (c == (unsigned char) Meta) {
 		    c = hgetc();
 #ifdef DEBUG
 		    if (lexstop) {
diff --git a/Src/math.c b/Src/math.c
index 777ad9c31..12c8d6f6b 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -955,7 +955,7 @@ getcvar(char *s)
 	    }
 	}
 #endif
-	mn.u.l = STOUC(*t == Meta ? t[1] ^ 32 : *t);
+	mn.u.l = (unsigned char) (*t == Meta ? t[1] ^ 32 : *t);
     }
     unqueue_signals();
     return mn;
diff --git a/Src/module.c b/Src/module.c
index bab4d8d73..6cf442270 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -2474,7 +2474,7 @@ bin_zmodload(char *nam, char **args, Options ops, UNUSED(int func))
 	return 1;
     }
     for (fp = fonly; *fp; fp++) {
-	if (OPT_ISSET(ops,STOUC(*fp)) && !OPT_ISSET(ops,'F')) {
+	if (OPT_ISSET(ops,(unsigned char) *fp) && !OPT_ISSET(ops,'F')) {
 	    zwarnnam(nam, "-%c is only allowed with -F", *fp);
 	    return 1;
 	}
diff --git a/Src/params.c b/Src/params.c
index f1fe38955..2e4a6eae2 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -732,7 +732,7 @@ split_env_string(char *env, char **name, char **value)
 
     tenv = strcpy(zhalloc(strlen(env) + 1), env);
     for (str = tenv; *str && *str != '='; str++) {
-	if (STOUC(*str) >= 128) {
+	if ((unsigned char) *str >= 128) {
 	    /*
 	     * We'll ignore environment variables with names not
 	     * from the portable character set since we don't
@@ -4123,7 +4123,8 @@ char *
 tiedarrgetfn(Param pm)
 {
     struct tieddata *dptr = (struct tieddata *)pm->u.data;
-    return *dptr->arrptr ? zjoin(*dptr->arrptr, STOUC(dptr->joinchar), 1) : "";
+    return *dptr->arrptr ?
+	    zjoin(*dptr->arrptr, (unsigned char) dptr->joinchar, 1) : "";
 }
 
 /**/
@@ -4819,12 +4820,12 @@ keyboardhacksetfn(UNUSED(Param pm), char *x)
 	    zwarn("Only one KEYBOARD_HACK character can be defined");  /* could be changed if needed */
 	}
 	for (i = 0; i < len; i++) {
-	    if (!isascii(STOUC(x[i]))) {
+	    if (!isascii((unsigned char) x[i])) {
 		zwarn("KEYBOARD_HACK can only contain ASCII characters");
 		return;
 	    }
 	}
-	keyboardhackchar = len ? STOUC(x[0]) : '\0';
+	keyboardhackchar = len ? (unsigned char) x[0] : '\0';
 	free(x);
     } else
 	keyboardhackchar = '\0';
@@ -4858,14 +4859,14 @@ histcharssetfn(UNUSED(Param pm), char *x)
 	if (len > 3)
 	    len = 3;
 	for (i = 0; i < len; i++) {
-	    if (!isascii(STOUC(x[i]))) {
+	    if (!isascii((unsigned char) x[i])) {
 		zwarn("HISTCHARS can only contain ASCII characters");
 		return;
 	    }
 	}
-	bangchar = len ? STOUC(x[0]) : '\0';
-	hatchar =  len > 1 ? STOUC(x[1]) : '\0';
-	hashchar = len > 2 ? STOUC(x[2]) : '\0';
+	bangchar = len ? (unsigned char) x[0] : '\0';
+	hatchar =  len > 1 ? (unsigned char) x[1] : '\0';
+	hashchar = len > 2 ? (unsigned char) x[2] : '\0';
 	free(x);
     } else {
 	bangchar = '!';
@@ -5087,7 +5088,7 @@ arrfixenv(char *s, char **t)
     if (pm->node.flags & PM_SPECIAL)
 	joinchar = ':';
     else
-	joinchar = STOUC(((struct tieddata *)pm->u.data)->joinchar);
+	joinchar = (unsigned char) ((struct tieddata *)pm->u.data)->joinchar;
 
     addenv(pm, t ? zjoin(t, joinchar, 1) : "");
 }
@@ -5109,9 +5110,9 @@ zputenv(char *str)
     char *ptr;
     int ret;
 
-    for (ptr = str; *ptr && STOUC(*ptr) < 128 && *ptr != '='; ptr++)
+    for (ptr = str; *ptr && (unsigned char) *ptr < 128 && *ptr != '='; ptr++)
 	;
-    if (STOUC(*ptr) >= 128) {
+    if ((unsigned char) *ptr >= 128) {
 	/*
 	 * Environment variables not in the portable character
 	 * set are non-standard and we don't really know of
@@ -6022,7 +6023,7 @@ printparamnode(HashNode hn, int printflags)
 	 * append the join char for tied parameters if different from colon
 	 * for typeset -p output.
 	 */
-	unsigned char joinchar = STOUC(((struct tieddata *)peer->u.data)->joinchar);
+	unsigned char joinchar = (unsigned char) ((struct tieddata *)peer->u.data)->joinchar;
 	if (joinchar != ':') {
 	    char buf[2];
 	    buf[0] = joinchar;
diff --git a/Src/parse.c b/Src/parse.c
index 2fac5c89c..283225b74 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -433,9 +433,9 @@ ecstrcode(char *s)
 	t = has_token(s);
 	wordcode c = (t ? 3 : 2);
 	switch (l) {
-	case 4: c |= ((wordcode) STOUC(s[2])) << 19;
-	case 3: c |= ((wordcode) STOUC(s[1])) << 11;
-	case 2: c |= ((wordcode) STOUC(s[0])) <<  3; break;
+	case 4: c |= ((wordcode) (unsigned char) s[2]) << 19;
+	case 3: c |= ((wordcode) (unsigned char) s[1]) << 11;
+	case 2: c |= ((wordcode) (unsigned char) s[0]) <<  3; break;
 	case 1: c = (t ? 7 : 6); break;
 	}
 	return c;
diff --git a/Src/pattern.c b/Src/pattern.c
index e947d1216..3edda1772 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -239,7 +239,7 @@ typedef unsigned long zrange_t;
  * a bit tricky...
  */
 #define WCHAR_INVALID(ch)			\
-    ((wchar_t) (0xDC00 + STOUC(ch)))
+    ((wchar_t) (0xDC00 + (unsigned char) ch))
 #endif /* MULTIBYTE_SUPPORT */
 
 /*
@@ -346,7 +346,7 @@ metacharinc(char **x)
      * set doesn't have the property that all bytes with the 8th
      * bit clear are single characters then we are stuffed.
      */
-    if (!(patglobflags & GF_MULTIBYTE) || !(STOUC(*inptr) & 0x80))
+    if (!(patglobflags & GF_MULTIBYTE) || !((unsigned char) *inptr & 0x80))
     {
 	if (itok(*inptr))
 	    inchar = ztokens[*inptr++ - Pound];
@@ -357,7 +357,7 @@ metacharinc(char **x)
 	    inchar = *inptr++;
 	}
 	*x = inptr;
-	return (wchar_t)STOUC(inchar);
+	return (wchar_t)(unsigned char) inchar;
     }
 
     while (*inptr) {
@@ -1181,8 +1181,8 @@ pattern_range_to_string(char *rangestr, char *outstr)
     int len = 0;
 
     while (*rangestr) {
-	if (imeta(STOUC(*rangestr))) {
-	    int swtype = STOUC(*rangestr) - STOUC(Meta);
+	if (imeta((unsigned char) *rangestr)) {
+	    int swtype = (unsigned char) *rangestr - (unsigned char) Meta;
 
 	    if (swtype == 0) {
 		/* Ordindary metafied character */
@@ -1278,17 +1278,17 @@ patcomppiece(int *flagp, int paren)
 	kshchar = '\0';
 	if (*patparse && patparse[1] == Inpar) {
 	    if (*patparse == zpc_special[ZPC_KSH_PLUS])
-		kshchar = STOUC('+');
+		kshchar = (unsigned char) '+';
 	    else if (*patparse == zpc_special[ZPC_KSH_BANG])
-		kshchar = STOUC('!');
+		kshchar = (unsigned char) '!';
 	    else if (*patparse == zpc_special[ZPC_KSH_BANG2])
-		kshchar = STOUC('!');
+		kshchar = (unsigned char) '!';
 	    else if (*patparse == zpc_special[ZPC_KSH_AT])
-		kshchar = STOUC('@');
+		kshchar = (unsigned char) '@';
 	    else if (*patparse == zpc_special[ZPC_KSH_STAR])
-		kshchar = STOUC('*');
+		kshchar = (unsigned char) '*';
 	    else if (*patparse == zpc_special[ZPC_KSH_QUEST])
-		kshchar = STOUC('?');
+		kshchar = (unsigned char) '?';
 	}
 
 	/*
@@ -1468,7 +1468,8 @@ patcomppiece(int *flagp, int paren)
 			ch = range_type(patparse, len);
 			patparse = nptr + 2;
 			if (ch != PP_UNKWN)
-			    patadd(NULL, STOUC(Meta) + ch, 1, PA_NOALIGN);
+			    patadd(NULL, (unsigned char) Meta + ch, 1,
+				PA_NOALIGN);
 			continue;
 		}
 		charstart = patparse;
@@ -1476,10 +1477,10 @@ patcomppiece(int *flagp, int paren)
 
 		if (*patparse == Dash && patparse[1] &&
 		    patparse[1] != Outbrack) {
-		    patadd(NULL, STOUC(Meta)+PP_RANGE, 1, PA_NOALIGN);
+		    patadd(NULL, (unsigned char) Meta+PP_RANGE, 1, PA_NOALIGN);
 		    if (itok(*charstart)) {
-			patadd(0, STOUC(ztokens[*charstart - Pound]), 1,
-			       PA_NOALIGN);
+			patadd(0, (unsigned char) ztokens[*charstart - Pound],
+			       1, PA_NOALIGN);
 		    } else {
 			patadd(charstart, 0, patparse-charstart, PA_NOALIGN);
 		    }
@@ -1487,7 +1488,7 @@ patcomppiece(int *flagp, int paren)
 		    METACHARINC(patparse);
 		}
 		if (itok(*charstart)) {
-		    patadd(0, STOUC(ztokens[*charstart - Pound]), 1,
+		    patadd(0, (unsigned char) ztokens[*charstart - Pound], 1,
 			   PA_NOALIGN);
 		} else {
 		    patadd(charstart, 0, patparse-charstart, PA_NOALIGN);
@@ -1910,8 +1911,8 @@ charref(char *x, char *y, int *zmb_ind)
     wchar_t wc;
     size_t ret;
 
-    if (!(patglobflags & GF_MULTIBYTE) || !(STOUC(*x) & 0x80))
-	return (wchar_t) STOUC(*x);
+    if (!(patglobflags & GF_MULTIBYTE) || !((unsigned char) *x & 0x80))
+	return (wchar_t) (unsigned char) *x;
 
     ret = mbrtowc(&wc, x, y-x, &shiftstate);
 
@@ -1937,7 +1938,7 @@ charnext(char *x, char *y)
     wchar_t wc;
     size_t ret;
 
-    if (!(patglobflags & GF_MULTIBYTE) || !(STOUC(*x) & 0x80))
+    if (!(patglobflags & GF_MULTIBYTE) || !((unsigned char) *x & 0x80))
 	return x + 1;
 
     ret = mbrtowc(&wc, x, y-x, &shiftstate);
@@ -1965,8 +1966,8 @@ charrefinc(char **x, char *y, int *z)
     wchar_t wc;
     size_t ret;
 
-    if (!(patglobflags & GF_MULTIBYTE) || !(STOUC(**x) & 0x80))
-	return (wchar_t) STOUC(*(*x)++);
+    if (!(patglobflags & GF_MULTIBYTE) || !((unsigned char) **x & 0x80))
+	return (wchar_t) (unsigned char) *(*x)++;
 
     ret = mbrtowc(&wc, *x, y-*x, &shiftstate);
 
@@ -2025,13 +2026,13 @@ charsub(char *x, char *y)
 #else /* no MULTIBYTE_SUPPORT */
 
 /* Get a character from the start point in a string */
-#define CHARREF(x, y)	(STOUC(*(x)))
+#define CHARREF(x, y)	((unsigned char) (*(x)))
 /* Get  a pointer to the next character */
 #define CHARNEXT(x, y)	((x)+1)
 /* Increment a pointer past the current character. */
 #define CHARINC(x, y)	((x)++)
 /* Get a character and increment */
-#define CHARREFINC(x, y, z)	(STOUC(*(x)++))
+#define CHARREFINC(x, y, z)	((unsigned char) (*(x)++))
 /* Counter the number of characters between two pointers, smaller first */
 #define CHARSUB(x,y)	((y) - (x))
 
@@ -2890,7 +2891,7 @@ patmatch(Upat prog)
 		}
 		if (!no && P_OP(next) == P_EXACTLY &&
 		    (!P_LS_LEN(next) ||
-		     !idigit(STOUC(*P_LS_STR(next)))) &&
+		     !idigit((unsigned char) (*P_LS_STR(next)))) &&
 		    !(patglobflags & 0xff))
 		    return 0;
 		patinput = --save;
@@ -3600,8 +3601,8 @@ mb_patmatchrange(char *range, wchar_t ch, int zmb_ind, wint_t *indptr, int *mtp)
      * ranges specially.
      */
     while (*range) {
-	if (imeta(STOUC(*range))) {
-	    int swtype = STOUC(*range++) - STOUC(Meta);
+	if (imeta((unsigned char) *range)) {
+	    int swtype = (unsigned char) *range++ - (unsigned char) Meta;
 	    if (mtp)
 		*mtp = swtype;
 	    switch (swtype) {
@@ -3753,8 +3754,8 @@ mb_patmatchindex(char *range, wint_t ind, wint_t *chr, int *mtp)
     *mtp = 0;
 
     while (*range) {
-	if (imeta(STOUC(*range))) {
-	    int swtype = STOUC(*range++) - STOUC(Meta);
+	if (imeta((unsigned char) *range)) {
+	    int swtype = (unsigned char) *range++ - (unsigned char) Meta;
 	    switch (swtype) {
 	    case 0:
 		range--;
@@ -3845,13 +3846,13 @@ patmatchrange(char *range, int ch, int *indptr, int *mtp)
      * ranges specially.
      */
     for (; *range; range++) {
-	if (imeta(STOUC(*range))) {
-	    int swtype = STOUC(*range) - STOUC(Meta);
+	if (imeta((unsigned char) *range)) {
+	    int swtype = (unsigned char) *range - (unsigned char) Meta;
 	    if (mtp)
 		*mtp = swtype;
 	    switch (swtype) {
 	    case 0:
-		if (STOUC(*++range ^ 32) == ch)
+		if ((unsigned char) (*++range ^ 32) == ch)
 		    return 1;
 		break;
 	    case PP_ALPHA:
@@ -3931,9 +3932,9 @@ patmatchrange(char *range, int ch, int *indptr, int *mtp)
 		break;
 	    case PP_RANGE:
 		range++;
-		r1 = STOUC(UNMETA(range));
+		r1 = (unsigned char) UNMETA(range);
 		METACHARINC(range);
-		r2 = STOUC(UNMETA(range));
+		r2 = (unsigned char) UNMETA(range);
 		if (*range == Meta)
 		    range++;
 		if (r1 <= ch && ch <= r2) {
@@ -3955,7 +3956,7 @@ patmatchrange(char *range, int ch, int *indptr, int *mtp)
 		DPUTS(1, "BUG: unknown metacharacter in range.");
 		break;
 	    }
-	} else if (STOUC(*range) == ch) {
+	} else if ((unsigned char) *range == ch) {
 	    if (mtp)
 		*mtp = 0;
 	    return 1;
@@ -3989,12 +3990,12 @@ patmatchindex(char *range, int ind, int *chr, int *mtp)
     *mtp = 0;
 
     for (; *range; range++) {
-	if (imeta(STOUC(*range))) {
-	    int swtype = STOUC(*range) - STOUC(Meta);
+	if (imeta((unsigned char) *range)) {
+	    int swtype = (unsigned char) *range - (unsigned char) Meta;
 	    switch (swtype) {
 	    case 0:
 		/* ordinary metafied character */
-		rchr = STOUC(*++range) ^ 32;
+		rchr = (unsigned char) *++range ^ 32;
 		if (!ind) {
 		    *chr = rchr;
 		    return 1;
@@ -4028,9 +4029,9 @@ patmatchindex(char *range, int ind, int *chr, int *mtp)
 
 	    case PP_RANGE:
 		range++;
-		r1 = STOUC(UNMETA(range));
+		r1 = (unsigned char) UNMETA(range);
 		METACHARINC(range);
-		r2 = STOUC(UNMETA(range));
+		r2 = (unsigned char) UNMETA(range);
 		if (*range == Meta)
 		    range++;
 		rdiff = r2 - r1; 
@@ -4050,7 +4051,7 @@ patmatchindex(char *range, int ind, int *chr, int *mtp)
 	    }
 	} else {
 	    if (!ind) {
-		*chr = STOUC(*range);
+		*chr = (unsigned char) *range;
 		return 1;
 	    }
 	}
diff --git a/Src/prompt.c b/Src/prompt.c
index 092de63a4..3cb95039c 100644
--- a/Src/prompt.c
+++ b/Src/prompt.c
@@ -1666,7 +1666,7 @@ match_colour(const char **teststrp, int is_fg, int colour)
 	tc = TCBGCOLOUR;
     }
     if (teststrp) {
-	if (**teststrp == '#' && isxdigit(STOUC((*teststrp)[1]))) {
+	if (**teststrp == '#' && isxdigit((unsigned char) (*teststrp)[1])) {
 	    struct color_rgb color;
 	    char *end;
 	    zlong col = zstrtol(*teststrp+1, &end, 16);
diff --git a/Src/sort.c b/Src/sort.c
index 26949ad9c..ce2b4bbc3 100644
--- a/Src/sort.c
+++ b/Src/sort.c
@@ -138,7 +138,7 @@ eltpcmp(const void *a, const void *b)
 	int mul = 0;
 	for (; *as == *bs && *as; as++, bs++);
 #ifndef HAVE_STRCOLL
-	cmp = (int)STOUC(*as) - (int)STOUC(*bs);
+	cmp = (int) (unsigned char) *as - (int) (unsigned char) *bs;
 #endif
 	if (sortnumeric < 0) {
 	    if (*as == '-' && idigit(as[1]) && idigit(*bs)) {
@@ -159,7 +159,7 @@ eltpcmp(const void *a, const void *b)
 		    bs++;
 		for (; idigit(*as) && *as == *bs; as++, bs++);
 		if (idigit(*as) || idigit(*bs)) {
-		    cmp = mul * ((int)STOUC(*as) - (int)STOUC(*bs));
+		    cmp = mul * ((int) (unsigned char) *as - (int) (unsigned char) *bs);
 		    while (idigit(*as) && idigit(*bs))
 			as++, bs++;
 		    if (idigit(*as) && !idigit(*bs))
diff --git a/Src/subst.c b/Src/subst.c
index 0f98e6ea3..b8e4023e1 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -556,7 +556,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
 	for ( ; *x; x += l) {
 	    char c = (l = *x == Meta) ? x[1] ^ 32 : *x;
 	    l++;
-	    if (!iwsep(STOUC(c)))
+	    if (!iwsep((unsigned char) c))
 		break;
 	    *ms_flags |= MULTSUB_WS_AT_START;
 	}
@@ -573,7 +573,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
 	    convchar_t c;
 	    if (*x == Dash)
 		*x = '-';
-	    if (itok(STOUC(*x))) {
+	    if (itok((unsigned char) *x)) {
 		/* token, can't be separator, must be single byte */
 		rawc = *x;
 		l = 1;
@@ -582,7 +582,7 @@ multsub(char **s, int pf_flags, char ***a, int *isarr, char *sep,
 		if (!inq && !inp && WC_ZISTYPE(c, ISEP)) {
 		    *x = '\0';
 		    for (x += l; *x; x += l) {
-			if (itok(STOUC(*x))) {
+			if (itok((unsigned char) *x)) {
 			    /* as above */
 			    rawc = *x;
 			    l = 1;
diff --git a/Src/utils.c b/Src/utils.c
index edf5d3df7..32492a93b 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -86,7 +86,7 @@ set_widearray(char *mb_array, Widechar_array wca)
 	while (*mb_array) {
 	    int mblen;
 
-	    if (STOUC(*mb_array) <= 0x7f) {
+	    if ((unsigned char) *mb_array <= 0x7f) {
 		mb_array++;
 		*wcptr++ = (wchar_t)*mb_array;
 		continue;
@@ -2920,7 +2920,7 @@ read1char(int echo)
     restore_queue_signals(q);
     if (echo)
 	write_loop(SHTTY, &c, 1);
-    return STOUC(c);
+    return (unsigned char) c;
 }
 
 /**/
@@ -4123,20 +4123,20 @@ inittyptab(void)
 #endif
     /* typtab['.'] |= IIDENT; */ /* Allow '.' in variable names - broken */
     typtab['_'] = IIDENT | IUSER;
-    typtab['-'] = typtab['.'] = typtab[STOUC(Dash)] = IUSER;
+    typtab['-'] = typtab['.'] = typtab[(unsigned char) Dash] = IUSER;
     typtab[' '] |= IBLANK | INBLANK;
     typtab['\t'] |= IBLANK | INBLANK;
     typtab['\n'] |= INBLANK;
     typtab['\0'] |= IMETA;
-    typtab[STOUC(Meta)  ] |= IMETA;
-    typtab[STOUC(Marker)] |= IMETA;
-    for (t0 = (int)STOUC(Pound); t0 <= (int)STOUC(LAST_NORMAL_TOK); t0++)
+    typtab[(unsigned char) Meta  ] |= IMETA;
+    typtab[(unsigned char) Marker] |= IMETA;
+    for (t0 = (int) (unsigned char) Pound; t0 <= (int) (unsigned char) LAST_NORMAL_TOK; t0++)
 	typtab[t0] |= ITOK | IMETA;
-    for (t0 = (int)STOUC(Snull); t0 <= (int)STOUC(Nularg); t0++)
+    for (t0 = (int) (unsigned char) Snull; t0 <= (int) (unsigned char) Nularg; t0++)
 	typtab[t0] |= ITOK | IMETA | INULL;
     for (s = ifs ? ifs : EMULATION(EMULATE_KSH|EMULATE_SH) ?
 	DEFAULT_IFS_SH : DEFAULT_IFS; *s; s++) {
-	int c = STOUC(*s == Meta ? *++s ^ 32 : *s);
+	int c = (unsigned char) (*s == Meta ? *++s ^ 32 : *s);
 #ifdef MULTIBYTE_SUPPORT
 	if (!isascii(c)) {
 	    /* see comment for wordchars below */
@@ -4152,7 +4152,7 @@ inittyptab(void)
 	typtab[c] |= ISEP;
     }
     for (s = wordchars ? wordchars : DEFAULT_WORDCHARS; *s; s++) {
-	int c = STOUC(*s == Meta ? *++s ^ 32 : *s);
+	int c = (unsigned char) (*s == Meta ? *++s ^ 32 : *s);
 #ifdef MULTIBYTE_SUPPORT
 	if (!isascii(c)) {
 	    /*
@@ -4173,16 +4173,16 @@ inittyptab(void)
 	DEFAULT_IFS_SH : DEFAULT_IFS, &ifs_wide);
 #endif
     for (s = SPECCHARS; *s; s++)
-	typtab[STOUC(*s)] |= ISPECIAL;
+	typtab[(unsigned char) *s] |= ISPECIAL;
     if (typtab_flags & ZTF_SP_COMMA)
-	typtab[STOUC(',')] |= ISPECIAL;
+	typtab[(unsigned char) ','] |= ISPECIAL;
     if (isset(BANGHIST) && bangchar && (typtab_flags & ZTF_INTERACT)) {
 	typtab_flags |= ZTF_BANGCHAR;
 	typtab[bangchar] |= ISPECIAL;
     } else
 	typtab_flags &= ~ZTF_BANGCHAR;
     for (s = PATCHARS; *s; s++)
-	typtab[STOUC(*s)] |= IPATTERN;
+	typtab[(unsigned char) *s] |= IPATTERN;
 
     unqueue_signals();
 }
@@ -4193,10 +4193,10 @@ makecommaspecial(int yesno)
 {
     if (yesno != 0) {
 	typtab_flags |= ZTF_SP_COMMA;
-	typtab[STOUC(',')] |= ISPECIAL;
+	typtab[(unsigned char) ','] |= ISPECIAL;
     } else {
 	typtab_flags &= ~ZTF_SP_COMMA;
-	typtab[STOUC(',')] &= ~ISPECIAL;
+	typtab[(unsigned char) ','] &= ~ISPECIAL;
     }
 }
 
@@ -4336,7 +4336,7 @@ itype_end(const char *ptr, int itype, int once)
 
 		if (wc == WEOF) {
 		    /* invalid, treat as single character */
-		    int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr);
+		    int chr = (unsigned char) (*ptr == Meta ? ptr[1] ^ 32 : *ptr);
 		    /* in this case non-ASCII characters can't match */
 		    if (chr > 127 || !zistype(chr,itype))
 			break;
@@ -4375,7 +4375,7 @@ itype_end(const char *ptr, int itype, int once)
     } else
 #endif
 	for (;;) {
-	    int chr = STOUC(*ptr == Meta ? ptr[1] ^ 32 : *ptr);
+	    int chr = (unsigned char) (*ptr == Meta ? ptr[1] ^ 32 : *ptr);
 	    if (!zistype(chr,itype))
 		break;
 	    ptr += (*ptr == Meta) ? 2 : 1;
@@ -4983,11 +4983,11 @@ unmeta_one(const char *in, int *sz)
     *sz = mb_metacharlenconv_r(in, &wc, &wstate);
 #else
     if (in[0] == Meta) {
-      *sz = 2;
-      wc = STOUC(in[1] ^ 32);
+	*sz = 2;
+	wc = (unsigned char) (in[1] ^ 32);
     } else {
-      *sz = 1;
-      wc = STOUC(in[0]);
+	*sz = 1;
+	wc = (unsigned char) in[0];
     }
 #endif
     return wc;
@@ -5022,11 +5022,11 @@ ztrcmp(char const *s1, char const *s2)
 
     if(!(c1 = *s1))
 	c1 = -1;
-    else if(c1 == STOUC(Meta))
+    else if(c1 == (unsigned char) Meta)
 	c1 = *++s1 ^ 32;
     if(!(c2 = *s2))
 	c2 = -1;
-    else if(c2 == STOUC(Meta))
+    else if(c2 == (unsigned char) Meta)
 	c2 = *++s2 ^ 32;
 
     if(c1 == c2)
@@ -5458,7 +5458,7 @@ mb_metacharlenconv_r(const char *s, wint_t *wcp, mbstate_t *mbsp)
     const char *ptr;
     wchar_t wc;
 
-    if (STOUC(*s) <= 0x7f) {
+    if ((unsigned char) *s <= 0x7f) {
 	if (wcp)
 	    *wcp = (wint_t)*s;
 	return 1;
@@ -5516,10 +5516,10 @@ mb_metacharlenconv_r(const char *s, wint_t *wcp, mbstate_t *mbsp)
 mod_export int
 mb_metacharlenconv(const char *s, wint_t *wcp)
 {
-    if (!isset(MULTIBYTE) || STOUC(*s) <= 0x7f) {
+    if (!isset(MULTIBYTE) || (unsigned char) *s <= 0x7f) {
 	/* treat as single byte, possibly metafied */
 	if (wcp)
-	    *wcp = (wint_t)STOUC(*s == Meta ? s[1] ^ 32 : *s);
+	    *wcp = (wint_t)(unsigned char) (*s == Meta ? s[1] ^ 32 : *s);
 	return 1 + (*s == Meta);
     }
     /*
@@ -5581,7 +5581,7 @@ mb_metastrlenend(char *ptr, int width, char *eptr)
 	    inchar = *ptr;
 	ptr++;
 
-	if (complete && STOUC(inchar) <= STOUC(0x7f)) {
+	if (complete && (unsigned char) inchar <= (unsigned char) 0x7f) {
 	    /*
 	     * We rely on 7-bit US-ASCII as a subset, so skip
 	     * multibyte handling if we have such a character.
@@ -5657,7 +5657,7 @@ mb_charlenconv_r(const char *s, int slen, wint_t *wcp, mbstate_t *mbsp)
     const char *ptr;
     wchar_t wc;
 
-    if (slen && STOUC(*s) <= 0x7f) {
+    if (slen && (unsigned char) *s <= 0x7f) {
 	if (wcp)
 	    *wcp = (wint_t)*s;
 	return 1;
@@ -5698,7 +5698,7 @@ mb_charlenconv_r(const char *s, int slen, wint_t *wcp, mbstate_t *mbsp)
 mod_export int
 mb_charlenconv(const char *s, int slen, wint_t *wcp)
 {
-    if (!isset(MULTIBYTE) || STOUC(*s) <= 0x7f) {
+    if (!isset(MULTIBYTE) || (unsigned char) *s <= 0x7f) {
 	if (wcp)
 	    *wcp = (wint_t)*s;
 	return 1;
@@ -5717,7 +5717,7 @@ mod_export int
 metacharlenconv(const char *x, int *c)
 {
     /*
-     * Here we don't use STOUC() on the chars since they
+     * Here we don't use an (unsigned char)  cast on the chars since they
      * may be compared against other chars and this will fail
      * if chars are signed and the high bit is set.
      */
@@ -5779,7 +5779,7 @@ sb_niceformat(const char *s, FILE *stream, char **outstrp, int flags)
     eptr = ptr + umlen;
 
     while (ptr < eptr) {
-	int c = STOUC(*ptr);
+	int c = (unsigned char) *ptr;
 	if (c == '\'' && (flags & NICEFLAG_QUOTE)) {
 	    fmt = "\\'";
 	    newl = 2;
@@ -5996,9 +5996,9 @@ addunprintable(char *v, const char *u, const char *uend)
 	 */
 	int c;
 	if (*u == Meta)
-	    c = STOUC(*++u ^ 32);
+	    c = (unsigned char) (*++u ^ 32);
 	else
-	    c = STOUC(*u);
+	    c = (unsigned char) *u;
 	switch (c) {
 	case '\0':
 	    *v++ = '\\';
@@ -7104,7 +7104,7 @@ getkeystring(char *s, int *len, int how, int *misc)
 	    continue;
 #ifdef MULTIBYTE_SUPPORT
 	} else if ((how & GETKEY_SINGLE_CHAR) &&
-		   isset(MULTIBYTE) && STOUC(*s) > 127) {
+		   isset(MULTIBYTE) && (unsigned char) *s > 127) {
 	    wint_t wc;
 	    int len;
 	    len = mb_metacharlenconv(s, &wc);
@@ -7207,7 +7207,7 @@ getkeystring(char *s, int *len, int how, int *misc)
 	    t = tbuf;
 	}
 	if ((how & GETKEY_SINGLE_CHAR) && t != tmp) {
-	    *misc = STOUC(tmp[0]);
+	    *misc = (unsigned char) tmp[0];
 	    return s + 1;
 	}
     }
diff --git a/Src/zsh.h b/Src/zsh.h
index 6f68df6a4..b035a1184 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -135,19 +135,6 @@ struct mathfunc {
 #define STRMATHFUNC(name, func, id) \
     { NULL, name, MFF_STR, NULL, func, NULL, 0, 0, id }
 
-/* Character tokens are sometimes casted to (unsigned char)'s.         * 
- * Unfortunately, some compilers don't correctly cast signed to        * 
- * unsigned promotions; i.e. (int)(unsigned char)((char) -1) evaluates * 
- * to -1, instead of 255 like it should.  We circumvent the troubles   * 
- * of such shameful delinquency by casting to a larger unsigned type   * 
- * then back down to unsigned char.                                    */
-
-#ifdef BROKEN_SIGNED_TO_UNSIGNED_CASTING
-# define STOUC(X)	((unsigned char)(unsigned short)(X))
-#else
-# define STOUC(X)	((unsigned char)(X))
-#endif
-
 /* Meta together with the character following Meta denotes the character *
  * which is the exclusive or of 32 and the character following Meta.     *
  * This is used to represent characters which otherwise has special      *
diff --git a/Src/ztype.h b/Src/ztype.h
index 5c85b0cd7..8757fc733 100644
--- a/Src/ztype.h
+++ b/Src/ztype.h
@@ -43,7 +43,7 @@
 #define IWSEP    (1 << 13)
 #define INULL    (1 << 14)
 #define IPATTERN (1 << 15)
-#define zistype(X,Y) (typtab[STOUC(X)] & Y)
+#define zistype(X,Y) (typtab[(unsigned char) (X)] & Y)
 #define idigit(X) zistype(X,IDIGIT)
 #define ialnum(X) zistype(X,IALNUM)
 #define iblank(X) zistype(X,IBLANK)	/* blank, not including \n */
diff --git a/configure.ac b/configure.ac
index 074141d38..f340d2993 100644
--- a/configure.ac
+++ b/configure.ac
@@ -582,16 +582,6 @@ if test x$zsh_cv_c_have_union_init = xyes; then
   AC_DEFINE(HAVE_UNION_INIT)
 fi
 
-dnl  Checking if compiler correctly cast signed to unsigned.
-AC_CACHE_CHECK(if signed to unsigned casting is broken,
-zsh_cv_c_broken_signed_to_unsigned_casting,
-[AC_RUN_IFELSE([AC_LANG_SOURCE([[int main(){return((int)(unsigned char)((char) -1) == 255);}]])],[zsh_cv_c_broken_signed_to_unsigned_casting=yes],[zsh_cv_c_broken_signed_to_unsigned_casting=no],[zsh_cv_c_broken_signed_to_unsigned_casting=no])])
-AH_TEMPLATE([BROKEN_SIGNED_TO_UNSIGNED_CASTING],
-[Define to 1 if compiler incorrectly cast signed to unsigned.])
-if test x$zsh_cv_c_broken_signed_to_unsigned_casting = xyes; then
-  AC_DEFINE(BROKEN_SIGNED_TO_UNSIGNED_CASTING)
-fi
-
 dnl Checking if the compiler supports variable-length arrays
 AC_CACHE_CHECK(if the compiler supports variable-length arrays,
 zsh_cv_c_variable_length_arrays,