• new ksh_mbswidth
• fix: when printing menus (tab expansion, for instance), honour width of the multibyte characters printed • some int→bool while here
This commit is contained in:
parent
6c6be2a87e
commit
7ddf56dbbc
208
edit.c
208
edit.c
@ -5,7 +5,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.119 2008/04/01 21:50:57 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.120 2008/04/19 17:21:52 tg Exp $");
|
||||
|
||||
/* tty driver characters we are interested in */
|
||||
typedef struct {
|
||||
@ -29,8 +29,9 @@ static int x_getc(void);
|
||||
static void x_putcf(int);
|
||||
static bool x_mode(bool);
|
||||
static int x_do_comment(char *, int, int *);
|
||||
static void x_print_expansions(int, char *const *, int);
|
||||
static int x_cf_glob(int, const char *, int, int, int *, int *, char ***, int *);
|
||||
static void x_print_expansions(int, char *const *, bool);
|
||||
static int x_cf_glob(int, const char *, int, int, int *, int *, char ***,
|
||||
bool *);
|
||||
static int x_longest_prefix(int, char *const *);
|
||||
static int x_basename(const char *, const char *);
|
||||
static void x_free_words(int, char **);
|
||||
@ -55,7 +56,13 @@ static void glob_table(const char *, XPtrV *, struct table *);
|
||||
static void glob_path(int flags, const char *, XPtrV *, const char *);
|
||||
static int x_file_glob(int, const char *, int, char ***);
|
||||
static int x_command_glob(int, const char *, int, char ***);
|
||||
static int x_locate_word(const char *, int, int, int *, int *);
|
||||
static int x_locate_word(const char *, int, int, int *, bool *);
|
||||
|
||||
static size_t mbxtowc(unsigned *, const char *);
|
||||
static size_t wcxtomb(char *, unsigned);
|
||||
static int wcxwidth(unsigned);
|
||||
static int x_e_getmbc(char *);
|
||||
static char *utf_getcpfromcols(char *, int);
|
||||
|
||||
/* +++ generic editing functions +++ */
|
||||
|
||||
@ -162,15 +169,14 @@ x_putcf(int c)
|
||||
static int
|
||||
x_do_comment(char *buf, int bsize, int *lenp)
|
||||
{
|
||||
int i, j;
|
||||
int len = *lenp;
|
||||
int i, j, len = *lenp;
|
||||
|
||||
if (len == 0)
|
||||
return 1; /* somewhat arbitrary - it's what at&t ksh does */
|
||||
|
||||
/* Already commented? */
|
||||
if (buf[0] == '#') {
|
||||
int saw_nl = 0;
|
||||
bool saw_nl = false;
|
||||
|
||||
for (j = 0, i = 1; i < len; i++) {
|
||||
if (!saw_nl || buf[i] != '#')
|
||||
@ -203,11 +209,10 @@ x_do_comment(char *buf, int bsize, int *lenp)
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Common file/command completion code for vi/emacs */
|
||||
|
||||
|
||||
static void
|
||||
x_print_expansions(int nwords, char * const *words, int is_command)
|
||||
x_print_expansions(int nwords, char * const *words, bool is_command)
|
||||
{
|
||||
int use_copy = 0;
|
||||
bool use_copy = false;
|
||||
int prefix_len;
|
||||
XPtrV l = { NULL, NULL, NULL };
|
||||
|
||||
@ -230,7 +235,7 @@ x_print_expansions(int nwords, char * const *words, int is_command)
|
||||
if (i == nwords) {
|
||||
while (prefix_len > 0 && words[0][prefix_len - 1] != '/')
|
||||
prefix_len--;
|
||||
use_copy = 1;
|
||||
use_copy = true;
|
||||
XPinit(l, nwords + 1);
|
||||
for (i = 0; i < nwords; i++)
|
||||
XPput(l, words[i] + prefix_len);
|
||||
@ -258,8 +263,7 @@ x_print_expansions(int nwords, char * const *words, int is_command)
|
||||
static int
|
||||
x_file_glob(int flags __unused, const char *str, int slen, char ***wordsp)
|
||||
{
|
||||
char *toglob;
|
||||
char **words;
|
||||
char *toglob, **words;
|
||||
int nwords, i, idx, escaping;
|
||||
XPtrV w;
|
||||
struct source *s, *sold;
|
||||
@ -355,9 +359,7 @@ path_order_cmp(const void *aa, const void *bb)
|
||||
static int
|
||||
x_command_glob(int flags, const char *str, int slen, char ***wordsp)
|
||||
{
|
||||
char *toglob;
|
||||
char *pat;
|
||||
char *fpath;
|
||||
char *toglob, *pat, *fpath;
|
||||
int nwords;
|
||||
XPtrV w;
|
||||
struct block *l;
|
||||
@ -393,11 +395,9 @@ x_command_glob(int flags, const char *str, int slen, char ***wordsp)
|
||||
/* Sort entries */
|
||||
if (flags & XCF_FULLPATH) {
|
||||
/* Sort by basename, then path order */
|
||||
struct path_order_info *info;
|
||||
struct path_order_info *last_info = 0;
|
||||
struct path_order_info *info, *last_info = NULL;
|
||||
char **words = (char **)XPptrv(w);
|
||||
int path_order = 0;
|
||||
int i;
|
||||
int i, path_order = 0;
|
||||
|
||||
info = (struct path_order_info *)
|
||||
alloc(sizeof(struct path_order_info) * nwords, ATEMP);
|
||||
@ -444,15 +444,14 @@ x_command_glob(int flags, const char *str, int slen, char ***wordsp)
|
||||
|
||||
static int
|
||||
x_locate_word(const char *buf, int buflen, int pos, int *startp,
|
||||
int *is_commandp)
|
||||
bool *is_commandp)
|
||||
{
|
||||
int p;
|
||||
int start, end;
|
||||
|
||||
/* Bad call? Probably should report error */
|
||||
if (pos < 0 || pos > buflen) {
|
||||
*startp = pos;
|
||||
*is_commandp = 0;
|
||||
*is_commandp = false;
|
||||
return 0;
|
||||
}
|
||||
/* The case where pos == buflen happens to take care of itself... */
|
||||
@ -471,12 +470,12 @@ x_locate_word(const char *buf, int buflen, int pos, int *startp,
|
||||
}
|
||||
|
||||
if (is_commandp) {
|
||||
int iscmd;
|
||||
bool iscmd;
|
||||
int p = start - 1;
|
||||
|
||||
/* Figure out if this is a command */
|
||||
for (p = start - 1; p >= 0 && ksh_isspace(buf[p]);
|
||||
p--)
|
||||
;
|
||||
while (p >= 0 && ksh_isspace(buf[p]))
|
||||
p--;
|
||||
iscmd = p < 0 || vstrchr(";|&()`", buf[p]);
|
||||
if (iscmd) {
|
||||
/* If command has a /, path, etc. is not searched;
|
||||
@ -497,16 +496,15 @@ x_locate_word(const char *buf, int buflen, int pos, int *startp,
|
||||
|
||||
static int
|
||||
x_cf_glob(int flags, const char *buf, int buflen, int pos, int *startp,
|
||||
int *endp, char ***wordsp, int *is_commandp)
|
||||
int *endp, char ***wordsp, bool *is_commandp)
|
||||
{
|
||||
int len;
|
||||
int nwords;
|
||||
int len, nwords;
|
||||
char **words = NULL;
|
||||
int is_command;
|
||||
bool is_command;
|
||||
|
||||
len = x_locate_word(buf, buflen, pos, startp, &is_command);
|
||||
if (!(flags & XCF_COMMAND))
|
||||
is_command = 0;
|
||||
is_command = false;
|
||||
/* Don't do command globing on zero length strings - it takes too
|
||||
* long and isn't very useful. File globs are more likely to be
|
||||
* useful, so allow these.
|
||||
@ -535,8 +533,7 @@ x_cf_glob(int flags, const char *buf, int buflen, int pos, int *startp,
|
||||
static char *
|
||||
add_glob(const char *str, int slen)
|
||||
{
|
||||
char *toglob;
|
||||
char *s;
|
||||
char *toglob, *s;
|
||||
bool saw_slash = false;
|
||||
|
||||
if (slen < 0)
|
||||
@ -573,8 +570,7 @@ add_glob(const char *str, int slen)
|
||||
static int
|
||||
x_longest_prefix(int nwords, char * const * words)
|
||||
{
|
||||
int i, j;
|
||||
int prefix_len;
|
||||
int i, j, prefix_len;
|
||||
char *p;
|
||||
|
||||
if (nwords <= 0)
|
||||
@ -593,10 +589,8 @@ x_longest_prefix(int nwords, char * const * words)
|
||||
static void
|
||||
x_free_words(int nwords, char **words)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nwords; i++)
|
||||
afreechk(words[i]);
|
||||
while (nwords)
|
||||
afreechk(words[--nwords]);
|
||||
afree(words, ATEMP);
|
||||
}
|
||||
|
||||
@ -653,12 +647,8 @@ static void
|
||||
glob_path(int flags, const char *pat, XPtrV *wp, const char *lpath)
|
||||
{
|
||||
const char *sp, *p;
|
||||
char *xp;
|
||||
int staterr;
|
||||
int pathlen;
|
||||
int patlen;
|
||||
int oldsize, newsize, i, j;
|
||||
char **words;
|
||||
char *xp, **words;
|
||||
int staterr, pathlen, patlen, oldsize, newsize, i, j;
|
||||
XString xs;
|
||||
|
||||
patlen = strlen(pat) + 1;
|
||||
@ -750,15 +740,6 @@ x_escape(const char *s, size_t len, int (*putbuf_func)(const char *, size_t))
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/* +++ UTF-8 hack +++ */
|
||||
|
||||
static size_t mbxtowc(unsigned *, const char *);
|
||||
static size_t wcxtomb(char *, unsigned);
|
||||
static int wcxwidth(unsigned);
|
||||
static int x_e_getmbc(char *);
|
||||
static char *utf_getcpfromcols(char *, int);
|
||||
static void utf_ptradj(char *, char **);
|
||||
|
||||
/* UTF-8 hack: high-level functions */
|
||||
|
||||
#if HAVE_EXPSTMT
|
||||
@ -805,30 +786,67 @@ utf_widthadj(const char *src, const char **dst)
|
||||
return (width == -1 ? 2 : width);
|
||||
}
|
||||
|
||||
static void
|
||||
utf_ptradj(char *src, char **dst)
|
||||
int
|
||||
ksh_mbswidth(const char *s)
|
||||
{
|
||||
size_t len;
|
||||
unsigned int wc;
|
||||
int width = 0, cw;
|
||||
|
||||
if (!Flag(FUTFHACK))
|
||||
return (strlen(s));
|
||||
|
||||
while (*s)
|
||||
if (((len = mbxtowc(&wc, s)) == (size_t)-1) ||
|
||||
((cw = wcxwidth(wc)) == -1)) {
|
||||
s++;
|
||||
width += 1;
|
||||
} else {
|
||||
s += len;
|
||||
width += cw;
|
||||
}
|
||||
return (width);
|
||||
}
|
||||
|
||||
size_t
|
||||
utf_cptradj(const char *src, const char **dst)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (!Flag(FUTFHACK) || *(unsigned char *)src < 0xC2)
|
||||
if (!Flag(FUTFHACK) || *(const unsigned char *)src < 0xC2)
|
||||
len = 1;
|
||||
else if (*(unsigned char *)src < 0xE0)
|
||||
else if (*(const unsigned char *)src < 0xE0)
|
||||
len = 2;
|
||||
else if (*(unsigned char *)src < 0xF0)
|
||||
else if (*(const unsigned char *)src < 0xF0)
|
||||
len = 3;
|
||||
else
|
||||
len = 1;
|
||||
|
||||
if (len > 1)
|
||||
if ((*(unsigned char *)(src + 1) & 0xC0) != 0x80)
|
||||
if ((*(const unsigned char *)(src + 1) & 0xC0) != 0x80)
|
||||
len = 1;
|
||||
if (len > 2)
|
||||
if ((*(unsigned char *)(src + 2) & 0xC0) != 0x80)
|
||||
if ((*(const unsigned char *)(src + 2) & 0xC0) != 0x80)
|
||||
len = 2;
|
||||
if (dst)
|
||||
*dst = src + len;
|
||||
return (len);
|
||||
}
|
||||
|
||||
#if HAVE_EXPSTMT
|
||||
#define utf_ptradj(s,d) ({ \
|
||||
union mksh_cchack out; \
|
||||
char **dst = (d); \
|
||||
size_t rv; \
|
||||
\
|
||||
rv = utf_cptradj((s), &out.ro); \
|
||||
if (dst) \
|
||||
*dst = out.rw; \
|
||||
})
|
||||
#else
|
||||
#define utf_ptradj(s,d) utf_cptradj((s), (const char **)(d))
|
||||
#endif
|
||||
|
||||
static char *
|
||||
utf_getcpfromcols(char *p, int cols)
|
||||
{
|
||||
@ -939,8 +957,7 @@ static size_t
|
||||
mbxtowc(unsigned *dst, const char *src)
|
||||
{
|
||||
const unsigned char *s = (const unsigned char *)src;
|
||||
unsigned c, wc;
|
||||
unsigned count;
|
||||
unsigned int c, wc, count;
|
||||
|
||||
wc = *s++;
|
||||
if (wc < 0x80) {
|
||||
@ -989,7 +1006,7 @@ static size_t
|
||||
wcxtomb(char *src, unsigned wc)
|
||||
{
|
||||
unsigned char *s = (unsigned char *)src;
|
||||
unsigned count;
|
||||
unsigned int count;
|
||||
|
||||
if (wc > 0xFFFD)
|
||||
wc = 0xFFFD;
|
||||
@ -1967,9 +1984,8 @@ x_search_char_forw(int c __unused)
|
||||
static int
|
||||
x_search_char_back(int c __unused)
|
||||
{
|
||||
char *cp = xcp, *p;
|
||||
char tmp[4];
|
||||
int b;
|
||||
char *cp = xcp, *p, tmp[4];
|
||||
bool b;
|
||||
|
||||
if (x_e_getmbc(tmp) < 0) {
|
||||
x_e_putc2(7);
|
||||
@ -1986,13 +2002,13 @@ x_search_char_back(int c __unused)
|
||||
if ((tmp[1] && ((p+1) > xep)) ||
|
||||
(tmp[2] && ((p+2) > xep)))
|
||||
continue;
|
||||
b = 1;
|
||||
b = true;
|
||||
if (*p != tmp[0])
|
||||
b = 0;
|
||||
b = false;
|
||||
if (b && tmp[1] && p[1] != tmp[1])
|
||||
b = 0;
|
||||
b = false;
|
||||
if (b && tmp[2] && p[2] != tmp[2])
|
||||
b = 0;
|
||||
b = false;
|
||||
if (b)
|
||||
break;
|
||||
}
|
||||
@ -2329,7 +2345,7 @@ x_redraw(int limit)
|
||||
static int
|
||||
x_transpose(int c __unused)
|
||||
{
|
||||
unsigned tmpa, tmpb;
|
||||
unsigned int tmpa, tmpb;
|
||||
|
||||
/* What transpose is meant to do seems to be up for debate. This
|
||||
* is a general summary of the options; the text is abcd with the
|
||||
@ -2463,6 +2479,7 @@ static int
|
||||
x_meta_yank(int c __unused)
|
||||
{
|
||||
int len;
|
||||
|
||||
if ((x_last_command != XFUNC_yank && x_last_command != XFUNC_meta_yank) ||
|
||||
killstack[killtp] == 0) {
|
||||
killtp = killsp;
|
||||
@ -2572,8 +2589,7 @@ x_bind(const char *a1, const char *a2,
|
||||
{
|
||||
unsigned char f;
|
||||
int prefix, key;
|
||||
char *sp = NULL;
|
||||
char *m1, *m2;
|
||||
char *sp = NULL, *m1, *m2;
|
||||
bool hastilde;
|
||||
|
||||
if (x_tab == NULL) {
|
||||
@ -2802,10 +2818,8 @@ static int
|
||||
x_expand(int c __unused)
|
||||
{
|
||||
char **words;
|
||||
int nwords;
|
||||
int start, end;
|
||||
int is_command;
|
||||
int i;
|
||||
int start, end, nwords, i;
|
||||
bool is_command;
|
||||
|
||||
nwords = x_cf_glob(XCF_FILE, xbuf, xep - xbuf, xcp - xbuf,
|
||||
&start, &end, &words, &is_command);
|
||||
@ -2834,10 +2848,8 @@ do_complete(int flags, /* XCF_{COMMAND,FILE,COMMAND_FILE} */
|
||||
Comp_type type)
|
||||
{
|
||||
char **words;
|
||||
int nwords;
|
||||
int start, end, nlen, olen;
|
||||
int is_command;
|
||||
int completed = 0;
|
||||
int start, end, nlen, olen, nwords;
|
||||
bool is_command, completed = false;
|
||||
|
||||
nwords = x_cf_glob(flags, xbuf, xep - xbuf, xcp - xbuf,
|
||||
&start, &end, &words, &is_command);
|
||||
@ -2860,16 +2872,16 @@ do_complete(int flags, /* XCF_{COMMAND,FILE,COMMAND_FILE} */
|
||||
x_delete(olen, false);
|
||||
x_escape(words[0], nlen, x_do_ins);
|
||||
x_adjust();
|
||||
completed = 1;
|
||||
completed = true;
|
||||
}
|
||||
/* add space if single non-dir match */
|
||||
if (nwords == 1 && words[0][nlen - 1] != '/') {
|
||||
x_ins(" ");
|
||||
completed = 1;
|
||||
completed = true;
|
||||
}
|
||||
if (type == CT_COMPLIST && !completed) {
|
||||
x_print_expansions(nwords, words, is_command);
|
||||
completed = 1;
|
||||
completed = true;
|
||||
}
|
||||
if (completed)
|
||||
x_redraw(0);
|
||||
@ -3029,8 +3041,7 @@ x_e_puts(const char *s)
|
||||
static int
|
||||
x_set_arg(int c)
|
||||
{
|
||||
int n = 0;
|
||||
int first = 1;
|
||||
int n = 0, first = 1;
|
||||
|
||||
c &= 255; /* strip command prefix */
|
||||
for (; c >= 0 && ksh_isdigit(c); c = x_e_getc(), first = 0)
|
||||
@ -3073,9 +3084,8 @@ x_version(int c __unused)
|
||||
{
|
||||
char *o_xbuf = xbuf, *o_xend = xend;
|
||||
char *o_xbp = xbp, *o_xep = xep, *o_xcp = xcp;
|
||||
int lim = x_lastcp() - xbp;
|
||||
int vlen, lim = x_lastcp() - xbp;
|
||||
char *v = str_save(KSH_VERSION, ATEMP);
|
||||
int vlen;
|
||||
|
||||
xbuf = xbp = xcp = v;
|
||||
xend = xep = v + (vlen = strlen(v));
|
||||
@ -3117,8 +3127,7 @@ x_version(int c __unused)
|
||||
static int
|
||||
x_prev_histword(int c __unused)
|
||||
{
|
||||
char *rcp;
|
||||
char *cp;
|
||||
char *rcp, *cp;
|
||||
|
||||
cp = *histptr;
|
||||
if (!cp)
|
||||
@ -5264,14 +5273,10 @@ static int
|
||||
complete_word(int cmd, int count)
|
||||
{
|
||||
static struct edstate *buf;
|
||||
int rval;
|
||||
int nwords;
|
||||
int start, end;
|
||||
int rval, nwords, start, end, match_len;
|
||||
char **words;
|
||||
char *match;
|
||||
int match_len;
|
||||
int is_unique;
|
||||
int is_command;
|
||||
bool is_command, is_unique;
|
||||
|
||||
/* Undo previous completion */
|
||||
if (cmd == 0 && expanded == COMPLETE && buf) {
|
||||
@ -5328,7 +5333,7 @@ complete_word(int cmd, int count)
|
||||
} else
|
||||
match = words[count];
|
||||
match_len = strlen(match);
|
||||
is_unique = 1;
|
||||
is_unique = true;
|
||||
/* expanded = PRINT; next call undo */
|
||||
} else {
|
||||
match = words[0];
|
||||
@ -5369,10 +5374,9 @@ complete_word(int cmd, int count)
|
||||
static int
|
||||
print_expansions(struct edstate *est, int cmd __unused)
|
||||
{
|
||||
int nwords;
|
||||
int start, end;
|
||||
int start, end, nwords;
|
||||
char **words;
|
||||
int is_command;
|
||||
bool is_command;
|
||||
|
||||
nwords = x_cf_glob(XCF_COMMAND_FILE | XCF_FULLPATH,
|
||||
est->cbuf, est->linelen, est->cursor,
|
||||
|
17
exec.c
17
exec.c
@ -2,7 +2,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.41 2008/04/01 22:20:18 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.42 2008/04/19 17:21:53 tg Exp $");
|
||||
|
||||
static int comexec(struct op *, struct tbl *volatile, const char **,
|
||||
int volatile);
|
||||
@ -1337,8 +1337,7 @@ pr_menu(const char *const *ap)
|
||||
{
|
||||
struct select_menu_info smi;
|
||||
const char *const *pp;
|
||||
int nwidth, dwidth;
|
||||
int i, n;
|
||||
int nwidth, dwidth, i, n;
|
||||
|
||||
/* Width/column calculations were done once and saved, but this
|
||||
* means select can't be used recursively so we re-calculate each
|
||||
@ -1350,7 +1349,7 @@ pr_menu(const char *const *ap)
|
||||
* get dimensions of the list
|
||||
*/
|
||||
for (n = 0, nwidth = 0, pp = ap; *pp; n++, pp++) {
|
||||
i = strlen(*pp);
|
||||
i = ksh_mbswidth(*pp);
|
||||
nwidth = (i > nwidth) ? i : nwidth;
|
||||
}
|
||||
/*
|
||||
@ -1365,7 +1364,7 @@ pr_menu(const char *const *ap)
|
||||
smi.args = ap;
|
||||
smi.arg_width = nwidth;
|
||||
smi.num_width = dwidth;
|
||||
print_columns(shl_out, n, select_fmt_entry, (void *) &smi,
|
||||
print_columns(shl_out, n, select_fmt_entry, (void *)&smi,
|
||||
dwidth + nwidth + 2, 1);
|
||||
|
||||
return n;
|
||||
@ -1386,14 +1385,14 @@ int
|
||||
pr_list(char *const *ap)
|
||||
{
|
||||
char *const *pp;
|
||||
int nwidth;
|
||||
int i, n;
|
||||
int nwidth, i, n;
|
||||
|
||||
for (n = 0, nwidth = 0, pp = ap; *pp; n++, pp++) {
|
||||
i = strlen(*pp);
|
||||
i = ksh_mbswidth(*pp);
|
||||
nwidth = (i > nwidth) ? i : nwidth;
|
||||
}
|
||||
print_columns(shl_out, n, plain_fmt_entry, (const void *)ap, nwidth + 1, 0);
|
||||
print_columns(shl_out, n, plain_fmt_entry, (const void *)ap,
|
||||
nwidth + 1, 0);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
12
histrap.c
12
histrap.c
@ -3,7 +3,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.60 2008/04/02 16:55:06 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.61 2008/04/19 17:21:53 tg Exp $");
|
||||
|
||||
/*-
|
||||
* MirOS: This is the default mapping type, and need not be specified.
|
||||
@ -189,9 +189,13 @@ c_fc(const char **wp)
|
||||
hist_source->line - (int)(histptr - hp));
|
||||
shf_putc('\t', shl_stdout);
|
||||
/* print multi-line commands correctly */
|
||||
for (s = *hp; (t = strchr(s, '\n')); s = t)
|
||||
shf_fprintf(shl_stdout, "%.*s\t",
|
||||
(int)(++t - s), s);
|
||||
s = *hp;
|
||||
while ((t = strchr(s, '\n'))) {
|
||||
*t = '\0';
|
||||
shf_fprintf(shl_stdout, "%s\n\t", s);
|
||||
*t++ = '\n';
|
||||
s = t;
|
||||
}
|
||||
shf_fprintf(shl_stdout, "%s\n", s);
|
||||
}
|
||||
shf_flush(shl_stdout);
|
||||
|
7
misc.c
7
misc.c
@ -6,7 +6,7 @@
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.73 2008/04/16 21:56:02 tg Exp $\t"
|
||||
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.74 2008/04/19 17:21:54 tg Exp $\t"
|
||||
MKSH_SH_H_ID);
|
||||
|
||||
#undef USE_CHVT
|
||||
@ -958,10 +958,7 @@ print_columns(struct shf *shf, int n,
|
||||
const void *arg, int max_width, int prefcol)
|
||||
{
|
||||
char *str = (char *) alloc(max_width + 1, ATEMP);
|
||||
int i;
|
||||
int r, c;
|
||||
int rows, cols;
|
||||
int nspace;
|
||||
int i, r, c, rows, cols, nspace;
|
||||
|
||||
/* max_width + 1 for the space. Note that no space
|
||||
* is printed after the last column to avoid problems
|
||||
|
4
sh.h
4
sh.h
@ -8,7 +8,7 @@
|
||||
/* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */
|
||||
/* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */
|
||||
|
||||
#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.205 2008/04/16 21:56:03 tg Exp $"
|
||||
#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.206 2008/04/19 17:21:54 tg Exp $"
|
||||
#define MKSH_VERSION "R33 2008/04/16"
|
||||
|
||||
#if HAVE_SYS_PARAM_H
|
||||
@ -1219,6 +1219,8 @@ void x_init(void);
|
||||
int x_read(char *, size_t);
|
||||
int x_bind(const char *, const char *, int, int);
|
||||
/* UTF-8 hack stuff */
|
||||
size_t utf_cptradj(const char *, const char **);
|
||||
int ksh_mbswidth(const char *);
|
||||
int utf_widthadj(const char *, const char **);
|
||||
/* eval.c */
|
||||
char *substitute(const char *, int);
|
||||
|
19
shf.c
19
shf.c
@ -2,7 +2,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.17 2008/03/28 13:28:33 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/shf.c,v 1.18 2008/04/19 17:21:55 tg Exp $");
|
||||
|
||||
/* flags to shf_emptybuf() */
|
||||
#define EB_READSW 0x01 /* about to switch to reading */
|
||||
@ -598,9 +598,7 @@ shf_puts(const char *s, struct shf *shf)
|
||||
int
|
||||
shf_write(const char *buf, int nbytes, struct shf *shf)
|
||||
{
|
||||
int orig_nbytes = nbytes;
|
||||
int n;
|
||||
int ncopy;
|
||||
int n, ncopy, orig_nbytes = nbytes;
|
||||
|
||||
if (!(shf->flags & SHF_WR))
|
||||
internal_errorf("shf_write: flags %x", shf->flags);
|
||||
@ -918,7 +916,7 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
case 's':
|
||||
if (!(s = va_arg(args, const char *)))
|
||||
s = "(null)";
|
||||
len = strlen(s);
|
||||
len = ksh_mbswidth(s);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
@ -981,8 +979,17 @@ shf_vfprintf(struct shf *shf, const char *fmt, va_list args)
|
||||
|
||||
if (precision > 0) {
|
||||
nwritten += precision;
|
||||
for ( ; precision-- > 0 ; s++)
|
||||
if (Flag(FUTFHACK)) {
|
||||
const char *q = s;
|
||||
while (precision-- > 0)
|
||||
utf_cptradj(q, &q);
|
||||
do {
|
||||
shf_putc(*s, shf);
|
||||
} while (++s < q);
|
||||
} else while (precision-- > 0) {
|
||||
shf_putc(*s, shf);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (field > 0) {
|
||||
nwritten += field;
|
||||
|
29
var.c
29
var.c
@ -2,7 +2,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.51 2008/02/24 15:20:52 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.52 2008/04/19 17:21:55 tg Exp $");
|
||||
|
||||
/*
|
||||
* Variables
|
||||
@ -491,8 +491,9 @@ formatstr(struct tbl *vp, const char *s)
|
||||
{
|
||||
int olen, nlen;
|
||||
char *p, *q;
|
||||
size_t psiz;
|
||||
|
||||
olen = strlen(s);
|
||||
olen = ksh_mbswidth(s);
|
||||
|
||||
if (vp->flag & (RJUST|LJUST)) {
|
||||
if (!vp->u2.field) /* default field width */
|
||||
@ -501,25 +502,29 @@ formatstr(struct tbl *vp, const char *s)
|
||||
} else
|
||||
nlen = olen;
|
||||
|
||||
p = (char *) alloc(nlen + 1, ATEMP);
|
||||
p = (char *)alloc((psiz = nlen * /* MB_LEN_MAX */ 3 + 1), ATEMP);
|
||||
if (vp->flag & (RJUST|LJUST)) {
|
||||
int slen;
|
||||
int slen = olen, i;
|
||||
|
||||
if (vp->flag & RJUST) {
|
||||
const char *qq = s + olen;
|
||||
const char *qq = s;
|
||||
|
||||
for (i = 0; i < slen; ++i)
|
||||
utf_widthadj(qq, &qq);
|
||||
/* strip trailing spaces (at&t uses qq[-1] == ' ') */
|
||||
while (qq > s && ksh_isspace(qq[-1]))
|
||||
while (qq > s && ksh_isspace(qq[-1])) {
|
||||
--qq;
|
||||
slen = qq - s;
|
||||
if (slen > vp->u2.field) {
|
||||
s += slen - vp->u2.field;
|
||||
slen = vp->u2.field;
|
||||
--slen;
|
||||
}
|
||||
while (slen > vp->u2.field) {
|
||||
utf_widthadj(s, &s);
|
||||
--slen;
|
||||
}
|
||||
if (vp->u2.field - slen)
|
||||
memset(p, (vp->flag & ZEROFIL) ? '0' : ' ',
|
||||
vp->u2.field - slen);
|
||||
shf_snprintf(p + vp->u2.field - slen,
|
||||
nlen + 1 - (vp->u2.field - slen),
|
||||
psiz - (vp->u2.field - slen),
|
||||
"%.*s", slen, s);
|
||||
} else {
|
||||
/* strip leading spaces/zeros */
|
||||
@ -532,7 +537,7 @@ formatstr(struct tbl *vp, const char *s)
|
||||
vp->u2.field, vp->u2.field, s);
|
||||
}
|
||||
} else
|
||||
memcpy(p, s, olen + 1);
|
||||
memcpy(p, s, strlen(s) + 1);
|
||||
|
||||
if (vp->flag & UCASEV_AL) {
|
||||
for (q = p; *q; q++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user