X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fmisc.c;fp=src%2Fmisc.c;h=deb95c3067d3172b489e648769acbaaad93e8159;hb=96b43632c2aa206ac1ec0eb70b34847d58d52633;hp=74bafbefe3f39a72d8ac1eb8310ecc5b91531d5b;hpb=c87de5d0279a299eec916effc751961347ff5eeb;p=android-x86%2Fexternal-mksh.git diff --git a/src/misc.c b/src/misc.c index 74bafbe..deb95c3 100644 --- a/src/misc.c +++ b/src/misc.c @@ -30,7 +30,7 @@ #include #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 @@ -52,7 +52,7 @@ static const unsigned char *pat_scan(const unsigned char *, 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 *); @@ -93,12 +93,8 @@ setctypes(const char *s, int t) 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 */ @@ -126,6 +122,17 @@ Xcheck_grow(XString *xsp, const char *xp, size_t more) #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]) @@ -166,11 +173,11 @@ struct options_info { 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; @@ -178,7 +185,6 @@ options_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) shf_snprintf(buf, buflen, "%-*s %s", oi->opt_width, OFN(oi->opts[i]), Flag(oi->opts[i]) ? "on" : "off"); - return (buf); } static void @@ -545,7 +551,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++)); @@ -776,7 +782,7 @@ do_gmatch(const unsigned char *s, const unsigned char *se, } switch (*p++) { case '[': - if (sc == 0 || (p = cclass(p, sc)) == NULL) + if (sc == 0 || (p = gmatch_cclass(p, sc)) == NULL) return (0); break; @@ -889,7 +895,7 @@ do_gmatch(const unsigned char *s, const unsigned char *se, } 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; @@ -1007,7 +1013,7 @@ ksh_getopt(const char **argv, Getopt *go, const char *optionsp) 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; @@ -1220,7 +1226,7 @@ print_value_quoted(struct shf *shf, const char *s) */ 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; @@ -1249,17 +1255,20 @@ print_columns(struct shf *shf, unsigned int n, 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; } @@ -1270,18 +1279,19 @@ print_columns(struct shf *shf, unsigned int n, } 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); } @@ -1402,12 +1412,12 @@ do_realpath(const char *upath) /* 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); @@ -1510,7 +1520,7 @@ do_realpath(const char *upath) 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 @@ -1610,7 +1620,7 @@ make_path(const char *cwd, const char *file, if (!file) file = null; - if (file[0] == '/') { + if (mksh_abspath(file)) { *phys_pathp = 0; use_cdpath = false; } else { @@ -1627,15 +1637,15 @@ make_path(const char *cwd, const char *file, 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); @@ -1721,7 +1731,7 @@ simplify_path(char *p) 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) { @@ -1921,7 +1931,7 @@ c_cd(const char **wp) /* 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; @@ -1999,9 +2009,9 @@ chvt(const Getopt *go) #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); } } @@ -2194,8 +2204,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 +2214,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 +2231,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);