#include <grp.h>
#endif
-__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.219.2.3 2015/03/20 22:21:04 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.238 2015/07/10 19:36:36 tg Exp $");
#define KSH_CHVT_FLAG
#ifdef MKSH_SMALL
const unsigned char *, bool) MKSH_A_PURE;
static int do_gmatch(const unsigned char *, const unsigned char *,
const unsigned char *, const unsigned char *) MKSH_A_PURE;
-static const unsigned char *cclass(const unsigned char *, unsigned char)
+static const unsigned char *gmatch_cclass(const unsigned char *, unsigned char)
MKSH_A_PURE;
#ifdef KSH_CHVT_CODE
static void chvt(const Getopt *);
void
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(letters_uc, C_ALPHA);
+ setctypes(letters_lc, C_ALPHA);
chtypes['_'] |= C_ALPHA;
setctypes("0123456789", C_DIGIT);
/* \0 added automatically */
#define SHFLAGS_DEFNS
+#define FN(sname,cname,flags,ochar) \
+ static const struct { \
+ /* character flag (if any) */ \
+ char c; \
+ /* OF_* */ \
+ unsigned char optflags; \
+ /* long name of option */ \
+ char name[sizeof(sname)]; \
+ } shoptione_ ## cname = { \
+ ochar, flags, sname \
+ };
#include "sh_flags.gen"
#define OFC(i) (options[i][-2])
int opts[NELEM(options)];
};
-static char *options_fmt_entry(char *, size_t, unsigned int, const void *);
+static void options_fmt_entry(char *, size_t, unsigned int, const void *);
static void printoptions(bool);
/* format a single select menu item */
-static char *
+static void
options_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg)
{
const struct options_info *oi = (const struct options_info *)arg;
shf_snprintf(buf, buflen, "%-*s %s",
oi->opt_width, OFN(oi->opts[i]),
Flag(oi->opts[i]) ? "on" : "off");
- return (buf);
}
static void
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++));
}
switch (*p++) {
case '[':
- if (sc == 0 || (p = cclass(p, sc)) == NULL)
+ if (sc == 0 || (p = gmatch_cclass(p, sc)) == NULL)
return (0);
break;
}
static const unsigned char *
-cclass(const unsigned char *p, unsigned char sub)
+gmatch_cclass(const unsigned char *p, unsigned char sub)
{
unsigned char c, d;
bool notp, found = false;
const char *arg = argv[go->optind], flag = arg ? *arg : '\0';
go->p = 1;
- if (flag == '-' && arg[1] == '-' && arg[2] == '\0') {
+ if (flag == '-' && ksh_isdash(arg + 1)) {
go->optind++;
go->p = 0;
go->info |= GI_MINUSMINUS;
*/
void
print_columns(struct shf *shf, unsigned int n,
- char *(*func)(char *, size_t, unsigned int, const void *),
+ void (*func)(char *, size_t, unsigned int, const void *),
const void *arg, size_t max_oct, size_t max_colz, bool prefcol)
{
unsigned int i, r, c, rows, cols, nspace, max_col;
str = alloc(max_oct, ATEMP);
/*
- * We use (max_col + 1) to consider the space separator.
- * Note that no space is printed after the last column
- * to avoid problems with terminals that have auto-wrap.
+ * We use (max_col + 2) to consider the separator space.
+ * Note that no spaces are printed after the last column
+ * to avoid problems with terminals that have auto-wrap,
+ * but we need to also take this into account in x_cols.
*/
- cols = x_cols / (max_col + 1);
+ cols = (x_cols + 1) / (max_col + 2);
/* if we can only print one column anyway, skip the goo */
if (cols < 2) {
- for (i = 0; i < n; ++i)
- shf_fprintf(shf, "%s\n",
- (*func)(str, max_oct, i, arg));
+ for (i = 0; i < n; ++i) {
+ (*func)(str, max_oct, i, arg);
+ shf_puts(str, shf);
+ shf_putc('\n', shf);
+ }
goto out;
}
}
nspace = (x_cols - max_col * cols) / cols;
+ if (nspace < 2)
+ nspace = 2;
max_col = -max_col;
- if (nspace <= 0)
- nspace = 1;
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
- i = c * rows + r;
- if (i < n) {
- shf_fprintf(shf, "%*s", max_col,
- (*func)(str, max_oct, i, arg));
- if (c + 1 < cols)
- shf_fprintf(shf, "%*s", nspace, null);
- }
+ if ((i = c * rows + r) >= n)
+ break;
+ (*func)(str, max_oct, i, arg);
+ if (i + rows >= n)
+ shf_puts(str, shf);
+ else
+ shf_fprintf(shf, "%*s%*s",
+ max_col, str, nspace, null);
}
shf_putchar('\n', shf);
}
/* max. recursion depth */
int symlinks = 32;
- if (upath[0] == '/') {
+ if (mksh_abspath(upath)) {
/* upath is an absolute pathname */
strdupx(ipath, upath, ATEMP);
} else {
/* upath is a relative pathname, prepend cwd */
- if ((tp = ksh_get_wd()) == NULL || tp[0] != '/')
+ if ((tp = ksh_get_wd()) == NULL || !mksh_abspath(tp))
return (NULL);
ipath = shf_smprintf("%s%s%s", tp, "/", upath);
afree(tp, ATEMP);
tp = shf_smprintf("%s%s%s", ldest, *ip ? "/" : "", ip);
afree(ipath, ATEMP);
ip = ipath = tp;
- if (ldest[0] != '/') {
+ if (!mksh_abspath(ldest)) {
/* symlink target is a relative path */
xp = Xrestpos(xs, xp, pos);
} else
if (!file)
file = null;
- if (file[0] == '/') {
+ if (mksh_abspath(file)) {
*phys_pathp = 0;
use_cdpath = false;
} else {
if (!plist)
use_cdpath = false;
else if (use_cdpath) {
- char *pend;
+ char *pend = plist;
- for (pend = plist; *pend && *pend != ':'; pend++)
- ;
+ while (*pend && *pend != MKSH_PATHSEPC)
+ ++pend;
plen = pend - plist;
*cdpathp = *pend ? pend + 1 : NULL;
}
- if ((!use_cdpath || !plen || plist[0] != '/') &&
+ if ((!use_cdpath || !plen || !mksh_abspath(plist)) &&
(cwd && *cwd)) {
len = strlen(cwd);
XcheckN(*xsp, xp, len);
continue;
else if (len == 2 && tp[1] == '.') {
/* parent level, but how? */
- if (*p == '/')
+ if (mksh_abspath(p))
/* absolute path, only one way */
goto strip_last_component;
else if (dp > sp) {
/* Ignore failure (happens if readonly or integer) */
setstr(oldpwd_s, current_wd, KSH_RETURN_ERROR);
- if (Xstring(xs, xp)[0] != '/') {
+ if (!mksh_abspath(Xstring(xs, xp))) {
pwd = NULL;
} else if (!physical) {
goto norealpath_PWD;
#endif
}
}
- if ((fd = open(dv, O_RDWR | O_BINARY)) < 0) {
+ if ((fd = binopen2(dv, O_RDWR)) < 0) {
sleep(1);
- if ((fd = open(dv, O_RDWR | O_BINARY)) < 0) {
+ if ((fd = binopen2(dv, O_RDWR)) < 0) {
errorf("%s: %s %s", "chvt", "can't open", dv);
}
}
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;
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
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);