diff --git a/check.t b/check.t index 89eec88..081cf82 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.336 2009/10/30 00:57:35 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.337 2009/11/09 23:35:07 tg Exp $ # $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $ @@ -25,7 +25,7 @@ # http://www.research.att.com/~gsf/public/ifs.sh expected-stdout: - @(#)MIRBSD KSH R39 2009/10/30 + @(#)MIRBSD KSH R39 2009/11/09 description: Check version of shell. stdin: diff --git a/exec.c b/exec.c index ddb0f95..073e837 100644 --- a/exec.c +++ b/exec.c @@ -22,7 +22,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.67 2009/10/15 16:25:15 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.68 2009/11/09 23:35:09 tg Exp $"); static int comexec(struct op *, struct tbl *volatile, const char **, int volatile, volatile int *); @@ -1338,16 +1338,15 @@ do_selectargs(const char **ap, bool print_menu) } struct select_menu_info { - const char *const *args; - int arg_width; + const char * const *args; int num_width; }; -static char *select_fmt_entry(const void *, int, char *, int); +static char *select_fmt_entry(char *, int, int, const void *); /* format a single select menu item */ static char * -select_fmt_entry(const void *arg, int i, char *buf, int buflen) +select_fmt_entry(char *buf, int buflen, int i, const void *arg) { const struct select_menu_info *smi = (const struct select_menu_info *)arg; @@ -1361,66 +1360,73 @@ select_fmt_entry(const void *arg, int i, char *buf, int buflen) * print a select style menu */ int -pr_menu(const char *const *ap) +pr_menu(const char * const *ap) { struct select_menu_info smi; - const char *const *pp; - int nwidth, dwidth, i, n; + const char * const *pp; + int acols = 0, aocts = 0, i, n; - /* Width/column calculations were done once and saved, but this - * means select can't be used recursively so we re-calculate each - * time (could save in a structure that is returned, but its probably - * not worth the bother). + /* + * width/column calculations were done once and saved, but this + * means select can't be used recursively so we re-calculate + * each time (could save in a structure that is returned, but + * it's probably not worth the bother) */ /* * get dimensions of the list */ - for (n = 0, nwidth = 0, pp = ap; *pp; n++, pp++) { + for (n = 0, pp = ap; *pp; n++, pp++) { + i = strlen(*pp); + if (i > aocts) + aocts = i; i = utf_mbswidth(*pp); - nwidth = (i > nwidth) ? i : nwidth; + if (i > acols) + acols = i; } + /* - * we will print an index of the form - * %d) - * in front of each entry - * get the max width of this + * we will print an index of the form "%d) " in front of + * each entry, so get the maximum width of this */ - for (i = n, dwidth = 1; i >= 10; i /= 10) - dwidth++; + for (i = n, smi.num_width = 1; i >= 10; i /= 10) + smi.num_width++; smi.args = ap; - smi.arg_width = nwidth; - smi.num_width = dwidth; print_columns(shl_out, n, select_fmt_entry, (void *)&smi, - dwidth + nwidth + 2, 1); + smi.num_width + 2 + aocts, smi.num_width + 2 + acols, + true); return (n); } /* XXX: horrible kludge to fit within the framework */ - -static char *plain_fmt_entry(const void *, int, char *, int); +static char *plain_fmt_entry(char *, int, int, const void *); static char * -plain_fmt_entry(const void *arg, int i, char *buf, int buflen) +plain_fmt_entry(char *buf, int buflen, int i, const void *arg) { shf_snprintf(buf, buflen, "%s", ((const char * const *)arg)[i]); return (buf); } int -pr_list(char *const *ap) +pr_list(char * const *ap) { - char *const *pp; - int nwidth, i, n; + int acols = 0, aocts = 0, i, n; + char * const *pp; - for (n = 0, nwidth = 0, pp = ap; *pp; n++, pp++) { + for (n = 0, pp = ap; *pp; n++, pp++) { + i = strlen(*pp); + if (i > aocts) + aocts = i; i = utf_mbswidth(*pp); - nwidth = (i > nwidth) ? i : nwidth; + if (i > acols) + acols = i; } + print_columns(shl_out, n, plain_fmt_entry, (const void *)ap, - nwidth + 1, 0); + aocts, acols, false); return (n); } diff --git a/funcs.c b/funcs.c index 4c336aa..2a8b786 100644 --- a/funcs.c +++ b/funcs.c @@ -25,7 +25,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.141 2009/10/27 17:00:01 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.142 2009/11/09 23:35:09 tg Exp $"); #if HAVE_KILLPG /* @@ -171,7 +171,7 @@ static int test_primary(Test_env *, bool); static int ptest_isa(Test_env *, Test_meta); static const char *ptest_getopnd(Test_env *, Test_op, bool); static void ptest_error(Test_env *, int, const char *); -static char *kill_fmt_entry(const void *, int, char *, int); +static char *kill_fmt_entry(char *, int, int, const void *); static void p_time(struct shf *, bool, long, int, int, const char *, const char *) __attribute__((nonnull (6, 7))); static char *do_realpath(const char *); @@ -1467,7 +1467,7 @@ c_fgbg(const char **wp) /* format a single kill item */ static char * -kill_fmt_entry(const void *arg, int i, char *buf, int buflen) +kill_fmt_entry(char *buf, int buflen, int i, const void *arg) { const struct kill_info *ki = (const struct kill_info *)arg; @@ -1538,25 +1538,29 @@ c_kill(const char **wp) shprintf("%d\n", n); } } else { - int w, j; - int mess_width; + int w, j, mess_cols, mess_octs; struct kill_info ki; for (j = NSIG, ki.num_width = 1; j >= 10; j /= 10) ki.num_width++; - ki.name_width = mess_width = 0; + ki.name_width = mess_cols = mess_octs = 0; for (j = 0; j < NSIG; j++) { w = strlen(sigtraps[j].name); if (w > ki.name_width) ki.name_width = w; w = strlen(sigtraps[j].mess); - if (w > mess_width) - mess_width = w; + if (w > mess_octs) + mess_octs = w; + w = utf_mbswidth(sigtraps[j].mess); + if (w > mess_cols) + mess_cols = w; } print_columns(shl_stdout, NSIG - 1, kill_fmt_entry, (void *)&ki, - ki.num_width + ki.name_width + mess_width + 3, 1); + ki.num_width + 1 + ki.name_width + 1 + mess_octs, + ki.num_width + 1 + ki.name_width + 1 + mess_cols, + true); } return (0); } diff --git a/misc.c b/misc.c index 8313660..f49a39c 100644 --- a/misc.c +++ b/misc.c @@ -29,7 +29,7 @@ #include <grp.h> #endif -__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.128 2009/10/30 14:37:43 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.129 2009/11/09 23:35:10 tg Exp $"); unsigned char chtypes[UCHAR_MAX + 1]; /* type bits for unsigned char */ @@ -120,12 +120,12 @@ struct options_info { int opts[NELEM(options)]; }; -static char *options_fmt_entry(const void *arg, int, char *, int); -static void printoptions(int); +static char *options_fmt_entry(char *, int, int, const void *); +static void printoptions(bool); /* format a single select menu item */ static char * -options_fmt_entry(const void *arg, int i, char *buf, int buflen) +options_fmt_entry(char *buf, int buflen, int i, const void *arg) { const struct options_info *oi = (const struct options_info *)arg; @@ -136,32 +136,40 @@ options_fmt_entry(const void *arg, int i, char *buf, int buflen) } static void -printoptions(int verbose) +printoptions(bool verbose) { - unsigned int i; + int i = 0; if (verbose) { + int n = 0, len, octs = 0; struct options_info oi; - int n, len; /* verbose version */ shf_puts("Current option settings\n", shl_stdout); - for (i = n = oi.opt_width = 0; i < NELEM(options); i++) + oi.opt_width = 0; + while (i < (int)NELEM(options)) { if (options[i].name) { - len = strlen(options[i].name); oi.opts[n++] = i; + len = strlen(options[i].name); + if (len > octs) + octs = len; + len = utf_mbswidth(options[i].name); if (len > oi.opt_width) oi.opt_width = len; } + ++i; + } print_columns(shl_stdout, n, options_fmt_entry, &oi, - oi.opt_width + 5, 1); + octs + 4, oi.opt_width + 4, true); } else { - /* short version ala ksh93 */ + /* short version รก la AT&T ksh93 */ shf_puts("set", shl_stdout); - for (i = 0; i < NELEM(options); i++) + while (i < (int)NELEM(options)) { if (Flag(i) && options[i].name) shprintf(" -o %s", options[i].name); + ++i; + } shf_putc('\n', shl_stdout); } } @@ -899,53 +907,64 @@ print_value_quoted(const char *s) shf_putc('\'', shl_stdout); } -/* Print things in columns and rows - func() is called to format the ith - * element +/* + * Print things in columns and rows - func() is called to format + * the i-th element */ void print_columns(struct shf *shf, int n, - char *(*func) (const void *, int, char *, int), - const void *arg, int max_width, int prefcol) + char *(*func)(char *, int, int, const void *), + const void *arg, int max_oct, int max_col, bool prefcol) { - char *str = alloc(max_width + 1, ATEMP); int i, r, c, rows, cols, nspace; + char *str; + + if (n <= 0) { +#ifndef MKSH_SMALL + internal_warningf("print_columns called with n=%d <= 0", n); +#endif + return; + } + + ++max_oct; + str = alloc(max_oct, ATEMP); /* ensure x_cols is valid first */ if (x_cols < MIN_COLS) change_winsz(); - /* max_width + 1 for the space. Note that no space - * is printed after the last column to avoid problems - * with terminals that have auto-wrap. + /* + * 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. */ - cols = x_cols / (max_width + 1); + cols = x_cols / (max_col + 1); + /* 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)(arg, i, str, max_width + 1)); + (*func)(str, max_oct, i, arg)); goto out; } - rows = (n + cols - 1) / cols; - if (prefcol && n && cols > rows) { - int tmp = rows; - rows = cols; - cols = tmp; - if (rows > n) - rows = n; + rows = (n + cols - 1) / cols; + if (prefcol && cols > rows) { + i = rows; + rows = cols > n ? n : cols; + cols = i; } - nspace = (x_cols - max_width * cols) / cols; + max_col = -max_col; + nspace = (x_cols + max_col * cols) / cols; 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_width, - (*func)(arg, i, str, max_width + 1)); + shf_fprintf(shf, "%*s", max_col, + (*func)(str, max_oct, i, arg)); if (c + 1 < cols) shf_fprintf(shf, "%*s", nspace, null); } diff --git a/sh.h b/sh.h index 5d83391..5ce64af 100644 --- a/sh.h +++ b/sh.h @@ -134,9 +134,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.359 2009/10/30 00:57:38 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.360 2009/11/09 23:35:11 tg Exp $"); #endif -#define MKSH_VERSION "R39 2009/10/30" +#define MKSH_VERSION "R39 2009/11/09" #ifndef MKSH_INCLUDES_ONLY @@ -1352,8 +1352,8 @@ struct tbl *findcom(const char *, int); void flushcom(int); const char *search(const char *, const char *, int, int *); int search_access(const char *, int, int *); -int pr_menu(const char *const *); -int pr_list(char *const *); +int pr_menu(const char * const *); +int pr_list(char * const *); /* expr.c */ int evaluate(const char *, mksh_ari_t *, int, bool); int v_evaluate(struct tbl *, const char *, volatile int, bool); @@ -1546,8 +1546,8 @@ void ksh_getopt_reset(Getopt *, int); int ksh_getopt(const char **, Getopt *, const char *); void print_value_quoted(const char *); void print_columns(struct shf *, int, - char *(*)(const void *, int, char *, int), - const void *, int, int prefcol); + char *(*)(char *, int, int, const void *), + const void *, int, int, bool); void strip_nuls(char *, int); int blocking_read(int, char *, int) __bound_att__((bounded (buffer, 2, 3)));