more low-hanging fruits for EBCDIC; notes:
• ord() new, From: Daniel Richard G. <skunk@iSKUNK.ORG> ‣ used in some places • (c - '0') → ksh_numdig(c) # may take *x++ argument • (c - 'A') → ksh_numuc(c) # may NOT take *x+= argument ‣ idem for ksh_numlc(c) and 'a' ‣ these need changing for EBCDIC ‣ add testsuite for this • use macros more, they exist already often • use digits_lc[foo] instead of ('0' + foo), especially for letters • caught another ksh_eq case… • also caught a maybe-UB overflow check, but we don’t have TIME_T_MAX ☹
This commit is contained in:
parent
3eb806b72b
commit
609b311919
16
check.t
16
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.690 2015/04/19 19:18:03 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.691 2015/04/29 20:07:30 tg Exp $
|
||||
# -*- mode: sh -*-
|
||||
#-
|
||||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
@ -4545,6 +4545,20 @@ expected-stdout:
|
||||
64
|
||||
64
|
||||
---
|
||||
name: integer-base-8
|
||||
description:
|
||||
Check that base-36 works (full span)
|
||||
stdin:
|
||||
echo 1:$((36#109AZ)).
|
||||
typeset -i36 x=1691675
|
||||
echo 2:$x.
|
||||
typeset -Uui36 x
|
||||
echo 3:$x.
|
||||
expected-stdout:
|
||||
1:1691675.
|
||||
2:36#109az.
|
||||
3:36#109AZ.
|
||||
---
|
||||
name: integer-base-check-flat
|
||||
description:
|
||||
Check behaviour does not match POSuX (except if set -o posix),
|
||||
|
16
edit.c
16
edit.c
@ -28,7 +28,7 @@
|
||||
|
||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.284 2015/04/11 22:09:48 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.285 2015/04/29 20:07:31 tg Exp $");
|
||||
|
||||
/*
|
||||
* in later versions we might use libtermcap for this, but since external
|
||||
@ -2966,7 +2966,7 @@ x_set_arg(int c)
|
||||
/* strip command prefix */
|
||||
c &= 255;
|
||||
while (c >= 0 && ksh_isdigit(c)) {
|
||||
n = n * 10 + (c - '0');
|
||||
n = n * 10 + ksh_numdig(c);
|
||||
if (n > LINE)
|
||||
/* upper bound for repeat */
|
||||
goto x_set_arg_too_big;
|
||||
@ -3627,8 +3627,8 @@ vi_hook(int ch)
|
||||
return (1);
|
||||
cmdlen = 0;
|
||||
argc1 = 0;
|
||||
if (ch >= '1' && ch <= '9') {
|
||||
argc1 = ch - '0';
|
||||
if (ch >= ord('1') && ch <= ord('9')) {
|
||||
argc1 = ksh_numdig(ch);
|
||||
state = VARG1;
|
||||
} else {
|
||||
curcmd[cmdlen++] = ch;
|
||||
@ -3672,7 +3672,7 @@ vi_hook(int ch)
|
||||
|
||||
case VARG1:
|
||||
if (ksh_isdigit(ch))
|
||||
argc1 = argc1 * 10 + ch - '0';
|
||||
argc1 = argc1 * 10 + ksh_numdig(ch);
|
||||
else {
|
||||
curcmd[cmdlen++] = ch;
|
||||
state = nextstate(ch);
|
||||
@ -3681,8 +3681,8 @@ vi_hook(int ch)
|
||||
|
||||
case VEXTCMD:
|
||||
argc2 = 0;
|
||||
if (ch >= '1' && ch <= '9') {
|
||||
argc2 = ch - '0';
|
||||
if (ch >= ord('1') && ch <= ord('9')) {
|
||||
argc2 = ksh_numdig(ch);
|
||||
state = VARG2;
|
||||
return (0);
|
||||
} else {
|
||||
@ -3698,7 +3698,7 @@ vi_hook(int ch)
|
||||
|
||||
case VARG2:
|
||||
if (ksh_isdigit(ch))
|
||||
argc2 = argc2 * 10 + ch - '0';
|
||||
argc2 = argc2 * 10 + ksh_numdig(ch);
|
||||
else {
|
||||
if (argc1 == 0)
|
||||
argc1 = argc2;
|
||||
|
9
funcs.c
9
funcs.c
@ -38,7 +38,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.269 2015/04/29 18:32:43 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.270 2015/04/29 20:07:32 tg Exp $");
|
||||
|
||||
#if HAVE_KILLPG
|
||||
/*
|
||||
@ -1666,8 +1666,11 @@ c_umask(const char **wp)
|
||||
mode_t new_umask;
|
||||
|
||||
if (ksh_isdigit(*cp)) {
|
||||
for (new_umask = 0; *cp >= '0' && *cp <= '7'; cp++)
|
||||
new_umask = new_umask * 8 + (*cp - '0');
|
||||
new_umask = 0;
|
||||
while (*cp >= ord('0') && *cp <= ord('7')) {
|
||||
new_umask = new_umask * 8 + ksh_numdig(*cp);
|
||||
++cp;
|
||||
}
|
||||
if (*cp) {
|
||||
bi_errorf("bad number");
|
||||
return (1);
|
||||
|
4
lex.c
4
lex.c
@ -23,7 +23,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.200 2015/04/19 18:50:36 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.201 2015/04/29 20:07:33 tg Exp $");
|
||||
|
||||
/*
|
||||
* states while lexing word
|
||||
@ -920,7 +920,7 @@ yylex(int cf)
|
||||
goto no_iop;
|
||||
if (!ksh_isdigit(dp[c2 + 1]))
|
||||
goto no_iop;
|
||||
iop->unit = (iop->unit * 10) + dp[c2 + 1] - '0';
|
||||
iop->unit = iop->unit * 10 + ksh_numdig(dp[c2 + 1]);
|
||||
if (iop->unit >= FDBASE)
|
||||
goto no_iop;
|
||||
}
|
||||
|
34
main.c
34
main.c
@ -34,7 +34,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.292 2015/04/19 18:50:37 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.293 2015/04/29 20:07:33 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@ -1459,7 +1459,7 @@ check_fd(const char *name, int mode, const char **emsgp)
|
||||
if (name[0] == 'p' && !name[1])
|
||||
return (coproc_getfd(mode, emsgp));
|
||||
while (ksh_isdigit(*name)) {
|
||||
fd = (fd * 10) + *name - '0';
|
||||
fd = fd * 10 + ksh_numdig(*name);
|
||||
if (fd >= FDBASE) {
|
||||
if (emsgp)
|
||||
*emsgp = "file descriptor too large";
|
||||
@ -1613,28 +1613,20 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
|
||||
memcpy(cp, "/shXXXXXX.tmp", 14);
|
||||
/* point to the first of six Xes */
|
||||
cp += 3;
|
||||
/* generate random part of filename */
|
||||
len = -1;
|
||||
do {
|
||||
i = rndget() % 36;
|
||||
cp[++len] = i < 26 ? 'a' + i : '0' + i - 26;
|
||||
} while (len < 5);
|
||||
|
||||
/* cyclically attempt to open a temporary file */
|
||||
while ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR | O_BINARY,
|
||||
0600)) < 0) {
|
||||
if (errno != EEXIST)
|
||||
do {
|
||||
/* generate random part of filename */
|
||||
len = 0;
|
||||
do {
|
||||
cp[len++] = digits_lc[rndget() % 36];
|
||||
} while (len < 6);
|
||||
|
||||
/* check if this one works */
|
||||
if ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR | O_BINARY,
|
||||
0600)) < 0 && errno != EEXIST)
|
||||
goto maketemp_out;
|
||||
/* count down from z to a then from 9 to 0 */
|
||||
while (cp[len] == '0')
|
||||
if (!len--)
|
||||
goto maketemp_out;
|
||||
if (cp[len] == 'a')
|
||||
cp[len] = '9';
|
||||
else
|
||||
--cp[len];
|
||||
/* do another cycle */
|
||||
}
|
||||
} while (i < 0);
|
||||
|
||||
if (type == TT_FUNSUB) {
|
||||
/* map us high and mark as close-on-exec */
|
||||
|
34
misc.c
34
misc.c
@ -30,7 +30,7 @@
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.228 2015/04/29 18:38:52 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.229 2015/04/29 20:07:34 tg Exp $");
|
||||
|
||||
#define KSH_CHVT_FLAG
|
||||
#ifdef MKSH_SMALL
|
||||
@ -95,10 +95,8 @@ initctypes(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 'a'; c <= 'z'; c++)
|
||||
chtypes[c] |= C_ALPHA;
|
||||
for (c = 'A'; c <= 'Z'; c++)
|
||||
chtypes[c] |= C_ALPHA;
|
||||
setctypes(digits_uc, C_ALPHA);
|
||||
setctypes(digits_lc, C_ALPHA);
|
||||
chtypes['_'] |= C_ALPHA;
|
||||
setctypes("0123456789", C_DIGIT);
|
||||
/* \0 added automatically */
|
||||
@ -545,7 +543,7 @@ getn(const char *s, int *ai)
|
||||
if (num.u > 214748364U)
|
||||
/* overflow on multiplication */
|
||||
return (0);
|
||||
num.u = num.u * 10U + (unsigned int)(c - '0');
|
||||
num.u = num.u * 10U + (unsigned int)ksh_numdig(c);
|
||||
/* now: num.u <= 2147483649U */
|
||||
} while ((c = *s++));
|
||||
|
||||
@ -2194,8 +2192,8 @@ unbksl(bool cstyle, int (*fg)(void), void (*fp)(int))
|
||||
wc = 0;
|
||||
i = 3;
|
||||
while (i--)
|
||||
if ((c = (*fg)()) >= '0' && c <= '7')
|
||||
wc = (wc << 3) + (c - '0');
|
||||
if ((c = (*fg)()) >= ord('0') && c <= ord('7'))
|
||||
wc = (wc << 3) + ksh_numdig(c);
|
||||
else {
|
||||
(*fp)(c);
|
||||
break;
|
||||
@ -2204,13 +2202,13 @@ unbksl(bool cstyle, int (*fg)(void), void (*fp)(int))
|
||||
case 'U':
|
||||
i = 8;
|
||||
if (/* CONSTCOND */ 0)
|
||||
/* FALLTHROUGH */
|
||||
/* FALLTHROUGH */
|
||||
case 'u':
|
||||
i = 4;
|
||||
i = 4;
|
||||
if (/* CONSTCOND */ 0)
|
||||
/* FALLTHROUGH */
|
||||
/* FALLTHROUGH */
|
||||
case 'x':
|
||||
i = cstyle ? -1 : 2;
|
||||
i = cstyle ? -1 : 2;
|
||||
/**
|
||||
* x: look for a hexadecimal number with up to
|
||||
* two (C style: arbitrary) digits; convert
|
||||
@ -2221,12 +2219,12 @@ unbksl(bool cstyle, int (*fg)(void), void (*fp)(int))
|
||||
wc = 0;
|
||||
while (i--) {
|
||||
wc <<= 4;
|
||||
if ((c = (*fg)()) >= '0' && c <= '9')
|
||||
wc += c - '0';
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
wc += c - 'A' + 10;
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
wc += c - 'a' + 10;
|
||||
if ((c = (*fg)()) >= ord('0') && c <= ord('9'))
|
||||
wc += ksh_numdig(c);
|
||||
else if (c >= ord('A') && c <= ord('F'))
|
||||
wc += ksh_numuc(c) + 10;
|
||||
else if (c >= ord('a') && c <= ord('f'))
|
||||
wc += ksh_numlc(c) + 10;
|
||||
else {
|
||||
wc >>= 4;
|
||||
(*fp)(c);
|
||||
|
12
sh.h
12
sh.h
@ -169,7 +169,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.727 2015/04/29 19:11:57 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.728 2015/04/29 20:07:34 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R51 2015/04/19"
|
||||
|
||||
@ -466,6 +466,8 @@ EXTERN const char initvsn[] E_INIT("KSH_VERSION=@(#)" KSH_VERSIONNAME \
|
||||
|
||||
EXTERN const char digits_uc[] E_INIT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
EXTERN const char digits_lc[] E_INIT("0123456789abcdefghijklmnopqrstuvwxyz");
|
||||
#define letters_uc (digits_uc + 10)
|
||||
#define letters_lc (digits_lc + 10)
|
||||
|
||||
/*
|
||||
* Evil hack for const correctness due to API brokenness
|
||||
@ -924,16 +926,20 @@ extern unsigned char chtypes[];
|
||||
#define ctype(c, t) tobool( ((t) == C_SUBOP2) ? \
|
||||
(((c) == '#' || (c) == '%') ? 1 : 0) : \
|
||||
(chtypes[(unsigned char)(c)] & (t)) )
|
||||
#define ord(c) ((int)(unsigned char)(c))
|
||||
#define ksh_isalphx(c) ctype((c), C_ALPHA)
|
||||
#define ksh_isalnux(c) ctype((c), C_ALPHA | C_DIGIT)
|
||||
#define ksh_isdigit(c) (((c) >= '0') && ((c) <= '9'))
|
||||
#define ksh_islower(c) (((c) >= 'a') && ((c) <= 'z'))
|
||||
#define ksh_isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
|
||||
#define ksh_tolower(c) (((c) >= 'A') && ((c) <= 'Z') ? (c) - 'A' + 'a' : (c))
|
||||
#define ksh_toupper(c) (((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c))
|
||||
#define ksh_tolower(c) (ksh_isupper(c) ? (c) - 'A' + 'a' : (c))
|
||||
#define ksh_toupper(c) (ksh_islower(c) ? (c) - 'a' + 'A' : (c))
|
||||
#define ksh_isdash(s) (((s)[0] == '-') && ((s)[1] == '\0'))
|
||||
#define ksh_isspace(c) ((((c) >= 0x09) && ((c) <= 0x0D)) || ((c) == 0x20))
|
||||
#define ksh_eq(c,u,l) (((c) | 0x20) == (l))
|
||||
#define ksh_numdig(c) ((c) - ord('0'))
|
||||
#define ksh_numuc(c) ((c) - ord('A'))
|
||||
#define ksh_numlc(c) ((c) - ord('a'))
|
||||
|
||||
EXTERN int ifs0 E_INIT(' '); /* for "$*" */
|
||||
|
||||
|
20
shf.c
20
shf.c
@ -25,7 +25,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.64 2015/02/06 10:09:07 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.65 2015/04/29 20:07:35 tg Exp $");
|
||||
|
||||
/* flags to shf_emptybuf() */
|
||||
#define EB_READSW 0x01 /* about to switch to reading */
|
||||
@ -847,11 +847,11 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
if (ksh_isdigit(c)) {
|
||||
bool overflowed = false;
|
||||
|
||||
tmp = c - '0';
|
||||
tmp = ksh_numdig(c);
|
||||
while (c = *fmt++, ksh_isdigit(c)) {
|
||||
if (notok2mul(2147483647, tmp, 10))
|
||||
overflowed = true;
|
||||
tmp = tmp * 10 + c - '0';
|
||||
tmp = tmp * 10 + ksh_numdig(c);
|
||||
}
|
||||
--fmt;
|
||||
if (overflowed)
|
||||
@ -872,7 +872,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
/* nasty format */
|
||||
break;
|
||||
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
if (ksh_isupper(c)) {
|
||||
flags |= FL_UPPER;
|
||||
c = ksh_tolower(c);
|
||||
}
|
||||
@ -917,7 +917,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
/* FALLTHROUGH */
|
||||
case 'u':
|
||||
do {
|
||||
*--cp = lnum % 10 + '0';
|
||||
*--cp = digits_lc[lnum % 10];
|
||||
lnum /= 10;
|
||||
} while (lnum);
|
||||
|
||||
@ -933,7 +933,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
|
||||
case 'o':
|
||||
do {
|
||||
*--cp = (lnum & 0x7) + '0';
|
||||
*--cp = digits_lc[lnum & 0x7];
|
||||
lnum >>= 3;
|
||||
} while (lnum);
|
||||
|
||||
@ -945,7 +945,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
const char *digits = (flags & FL_UPPER) ?
|
||||
digits_uc : digits_lc;
|
||||
do {
|
||||
*--cp = digits[lnum & 0xf];
|
||||
*--cp = digits[lnum & 0xF];
|
||||
lnum >>= 4;
|
||||
} while (lnum);
|
||||
|
||||
@ -1013,7 +1013,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
s++;
|
||||
nwritten++;
|
||||
if (--precision > 0 &&
|
||||
(*s | 0x20) == 'x') {
|
||||
ksh_eq(*s, 'X', 'x')) {
|
||||
shf_putc(*s, shf);
|
||||
s++;
|
||||
precision--;
|
||||
@ -1025,8 +1025,10 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
c = flags & FL_ZERO ? '0' : ' ';
|
||||
if (field < 0) {
|
||||
nwritten += -field;
|
||||
for ( ; field < 0 ; field++)
|
||||
while (field < 0) {
|
||||
shf_putc(c, shf);
|
||||
++field;
|
||||
}
|
||||
}
|
||||
} else
|
||||
c = ' ';
|
||||
|
11
syn.c
11
syn.c
@ -23,7 +23,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.100 2015/04/11 22:03:32 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.101 2015/04/29 20:07:35 tg Exp $");
|
||||
|
||||
struct nesting_state {
|
||||
int start_token; /* token than began nesting (eg, FOR) */
|
||||
@ -214,10 +214,10 @@ synio(int cf)
|
||||
|
||||
if (iop->unit > 9) {
|
||||
*cp++ = CHAR;
|
||||
*cp++ = '0' + (iop->unit / 10);
|
||||
*cp++ = digits_lc[iop->unit / 10];
|
||||
}
|
||||
*cp++ = CHAR;
|
||||
*cp++ = '0' + (iop->unit % 10);
|
||||
*cp++ = digits_lc[iop->unit % 10];
|
||||
*cp = EOS;
|
||||
|
||||
iop->ioflag &= ~IOBASH;
|
||||
@ -1074,7 +1074,8 @@ parse_usec(const char *s, struct timeval *tv)
|
||||
tv->tv_sec = 0;
|
||||
/* parse integral part */
|
||||
while (ksh_isdigit(*s)) {
|
||||
tt.tv_sec = tv->tv_sec * 10 + (*s++ - '0');
|
||||
tt.tv_sec = tv->tv_sec * 10 + ksh_numdig(*s++);
|
||||
/*XXX this overflow check maybe UB */
|
||||
if (tt.tv_sec / 10 != tv->tv_sec) {
|
||||
errno = EOVERFLOW;
|
||||
return (true);
|
||||
@ -1095,7 +1096,7 @@ parse_usec(const char *s, struct timeval *tv)
|
||||
/* parse decimal fraction */
|
||||
i = 100000;
|
||||
while (ksh_isdigit(*s)) {
|
||||
tv->tv_usec += i * (*s++ - '0');
|
||||
tv->tv_usec += i * ksh_numdig(*s++);
|
||||
if (i == 1)
|
||||
break;
|
||||
i /= 10;
|
||||
|
8
var.c
8
var.c
@ -28,7 +28,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.191 2015/04/29 18:38:54 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.192 2015/04/29 20:07:35 tg Exp $");
|
||||
|
||||
/*-
|
||||
* Variables
|
||||
@ -553,11 +553,11 @@ getint(struct tbl *vp, mksh_ari_u *nump, bool arith)
|
||||
continue;
|
||||
}
|
||||
if (ksh_isdigit(c))
|
||||
c -= '0';
|
||||
c = ksh_numdig(c);
|
||||
else if (ksh_isupper(c))
|
||||
c -= 'A' - 10;
|
||||
c = ksh_numuc(c) + 10;
|
||||
else if (ksh_islower(c))
|
||||
c -= 'a' - 10;
|
||||
c = ksh_numlc(c) + 10;
|
||||
else
|
||||
return (-1);
|
||||
if (c >= base)
|
||||
|
Loading…
x
Reference in New Issue
Block a user