control character madness, but more compiler-friendly

This commit is contained in:
tg 2017-04-28 03:28:19 +00:00
parent 2482c8b73d
commit fba6940ba4
5 changed files with 177 additions and 107 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.780 2017/04/28 02:24:54 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.781 2017/04/28 03:28:14 tg Exp $
# -*- mode: sh -*-
#-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -9748,7 +9748,7 @@ stdin:
$'\J\K\L\M\N\O\P\Q\R\S\T\U1\V\W\X\Y\Z\[\\\]\^\_\`\a\b\d\e' \
$'\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u1\v\w\x1\y\z\{\|\}\~ $x' \
$'\u20acd' $'\U20acd' $'\x123' $'fn\x0rd' $'\0234' $'\234' \
$'\2345' $'\ca' $'\c!' $'\c?' $'\c' $'a\
$'\2345' $'\ca' $'\c!' $'\c?' $'\c' $'a\
b' | {
# integer-base-one-3As
typeset -Uui16 -Z11 pos=0
@ -9790,7 +9790,7 @@ expected-stdout:
00000050 68 69 6A 6B 6C 6D 0A 6F - 70 71 0D 73 09 01 0B 77 |hijklm.opq.s...w|
00000060 01 79 7A 7B 7C 7D 7E 20 - 24 78 0A E2 82 AC 64 0A |.yz{|}~ $x....d.|
00000070 EF BF BD 0A C4 A3 0A 66 - 6E 0A 13 34 0A 9C 0A 9C |.......fn..4....|
00000080 35 0A 01 0A 01 0A 7F 0A - 02 82 AC 0A 61 0A 62 0A |5...........a.b.|
00000080 35 0A 01 0A 01 0A 7F 0A - 82 80 A6 0A 61 0A 62 0A |5...........a.b.|
---
name: dollar-quotes-in-heredocs-strings
description:

174
edit.c
View File

@ -28,7 +28,7 @@
#ifndef MKSH_NO_CMDLINE_EDITING
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.331 2017/04/28 02:24:56 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.332 2017/04/28 03:28:17 tg Exp $");
/*
* in later versions we might use libtermcap for this, but since external
@ -1031,56 +1031,56 @@ static const struct x_ftab x_ftab[] = {
};
static struct x_defbindings const x_defbindings[] = {
{ XFUNC_del_back, 0, CTRL('?') },
{ XFUNC_del_bword, 1, CTRL('?') },
{ XFUNC_eot_del, 0, CTRL('D') },
{ XFUNC_del_back, 0, CTRL('H') },
{ XFUNC_del_bword, 1, CTRL('H') },
{ XFUNC_del_back, 0, CTRL_QM },
{ XFUNC_del_bword, 1, CTRL_QM },
{ XFUNC_eot_del, 0, CTRL_D },
{ XFUNC_del_back, 0, CTRL_H },
{ XFUNC_del_bword, 1, CTRL_H },
{ XFUNC_del_bword, 1, 'h' },
{ XFUNC_mv_bword, 1, 'b' },
{ XFUNC_mv_fword, 1, 'f' },
{ XFUNC_del_fword, 1, 'd' },
{ XFUNC_mv_back, 0, CTRL('B') },
{ XFUNC_mv_forw, 0, CTRL('F') },
{ XFUNC_search_char_forw, 0, CTRL(']') },
{ XFUNC_search_char_back, 1, CTRL(']') },
{ XFUNC_newline, 0, CTRL('M') },
{ XFUNC_newline, 0, CTRL('J') },
{ XFUNC_end_of_text, 0, CTRL('_') },
{ XFUNC_abort, 0, CTRL('G') },
{ XFUNC_prev_com, 0, CTRL('P') },
{ XFUNC_next_com, 0, CTRL('N') },
{ XFUNC_nl_next_com, 0, CTRL('O') },
{ XFUNC_search_hist, 0, CTRL('R') },
{ XFUNC_mv_back, 0, CTRL_B },
{ XFUNC_mv_forw, 0, CTRL_F },
{ XFUNC_search_char_forw, 0, CTRL_BC },
{ XFUNC_search_char_back, 1, CTRL_BC },
{ XFUNC_newline, 0, CTRL_M },
{ XFUNC_newline, 0, CTRL_J },
{ XFUNC_end_of_text, 0, CTRL_US },
{ XFUNC_abort, 0, CTRL_G },
{ XFUNC_prev_com, 0, CTRL_P },
{ XFUNC_next_com, 0, CTRL_N },
{ XFUNC_nl_next_com, 0, CTRL_O },
{ XFUNC_search_hist, 0, CTRL_R },
{ XFUNC_beg_hist, 1, '<' },
{ XFUNC_end_hist, 1, '>' },
{ XFUNC_goto_hist, 1, 'g' },
{ XFUNC_mv_end, 0, CTRL('E') },
{ XFUNC_mv_beg, 0, CTRL('A') },
{ XFUNC_draw_line, 0, CTRL('L') },
{ XFUNC_cls, 1, CTRL('L') },
{ XFUNC_meta1, 0, CTRL('[') },
{ XFUNC_meta2, 0, CTRL('X') },
{ XFUNC_kill, 0, CTRL('K') },
{ XFUNC_yank, 0, CTRL('Y') },
{ XFUNC_mv_end, 0, CTRL_E },
{ XFUNC_mv_beg, 0, CTRL_A },
{ XFUNC_draw_line, 0, CTRL_L },
{ XFUNC_cls, 1, CTRL_L },
{ XFUNC_meta1, 0, CTRL_BO },
{ XFUNC_meta2, 0, CTRL_X },
{ XFUNC_kill, 0, CTRL_K },
{ XFUNC_yank, 0, CTRL_Y },
{ XFUNC_meta_yank, 1, 'y' },
{ XFUNC_literal, 0, CTRL('^') },
{ XFUNC_literal, 0, CTRL_CA },
{ XFUNC_comment, 1, '#' },
{ XFUNC_transpose, 0, CTRL('T') },
{ XFUNC_complete, 1, CTRL('[') },
{ XFUNC_comp_list, 0, CTRL('I') },
{ XFUNC_transpose, 0, CTRL_T },
{ XFUNC_complete, 1, CTRL_BO },
{ XFUNC_comp_list, 0, CTRL_I },
{ XFUNC_comp_list, 1, '=' },
{ XFUNC_enumerate, 1, '?' },
{ XFUNC_expand, 1, '*' },
{ XFUNC_comp_file, 1, CTRL('X') },
{ XFUNC_comp_comm, 2, CTRL('[') },
{ XFUNC_comp_file, 1, CTRL_X },
{ XFUNC_comp_comm, 2, CTRL_BO },
{ XFUNC_list_comm, 2, '?' },
{ XFUNC_list_file, 2, CTRL('Y') },
{ XFUNC_list_file, 2, CTRL_Y },
{ XFUNC_set_mark, 1, ' ' },
{ XFUNC_kill_region, 0, CTRL('W') },
{ XFUNC_xchg_point_mark, 2, CTRL('X') },
{ XFUNC_literal, 0, CTRL('V') },
{ XFUNC_version, 1, CTRL('V') },
{ XFUNC_kill_region, 0, CTRL_W },
{ XFUNC_xchg_point_mark, 2, CTRL_X },
{ XFUNC_literal, 0, CTRL_V },
{ XFUNC_version, 1, CTRL_V },
{ XFUNC_prev_histword, 1, '.' },
{ XFUNC_prev_histword, 1, '_' },
{ XFUNC_set_arg, 1, '0' },
@ -1143,7 +1143,7 @@ static struct x_defbindings const x_defbindings[] = {
#endif
#ifndef MKSH_SMALL
/* more non-standard ones */
{ XFUNC_eval_region, 1, CTRL('E') },
{ XFUNC_eval_region, 1, CTRL_E },
{ XFUNC_edit_line, 2, 'e' }
#endif
};
@ -1642,7 +1642,7 @@ x_size2(char *cp, char **dcp)
if (c == '\t')
/* Kludge, tabs are always four spaces. */
return (4);
if (ISCTRL(c) && /* but not C1 */ c < 0x80)
if (ksh_isctrl(c))
/* control unsigned char */
return (2);
return (1);
@ -1667,9 +1667,9 @@ x_zotc3(char **cp)
/* Kludge, tabs are always four spaces. */
x_e_puts(T4spaces);
(*cp)++;
} else if (ISCTRL(c) && /* but not C1 */ c < 0x80) {
} else if (ksh_isctrl(c)) {
x_e_putc2('^');
x_e_putc2(UNCTRL(c));
x_e_putc2(ksh_unctrl(c));
(*cp)++;
} else
x_e_putc3((const char **)cp);
@ -1782,7 +1782,7 @@ x_end_of_text(int c MKSH_A_UNUSED)
unsigned char tmp[1], *cp = tmp;
*tmp = isedchar(edchars.eof) ? (unsigned char)edchars.eof :
(unsigned char)CTRL('D');
(unsigned char)CTRL_D;
x_zotc3((char **)&cp);
x_putc('\r');
x_putc('\n');
@ -1897,13 +1897,13 @@ x_search_hist(int c)
if ((c = x_e_getc()) < 0)
return (KSTD);
f = x_tab[0][c];
if (c == CTRL('[')) {
if (c == CTRL_BO) {
if ((f & 0x7F) == XFUNC_meta1) {
if ((c = x_e_getc()) < 0)
return (KSTD);
f = x_tab[1][c] & 0x7F;
if (f == XFUNC_meta1 || f == XFUNC_meta2)
x_meta1(CTRL('['));
x_meta1(CTRL_BO);
x_e_ungetc(c);
}
break;
@ -2398,9 +2398,8 @@ x_mapin(const char *cp, Area *ap)
if (*cp == '^') {
cp++;
/*XXX or ^^ escape? this is ugly. */
if (*cp >= '?')
/* includes '?'; ASCII */
*op++ = CTRL(*cp);
if (rtt2asc(*cp) >= 0x3FU)
*op++ = ksh_toctrl(*cp);
else {
*op++ = '^';
cp--;
@ -2419,9 +2418,9 @@ x_mapout2(int c, char **buf)
{
char *p = *buf;
if (ISCTRL(c)) {
if (ksh_isctrl(c)) {
*p++ = '^';
*p++ = UNCTRL(c);
*p++ = ksh_unctrl(c);
} else
*p++ = c;
*p = 0;
@ -2444,9 +2443,9 @@ x_print(int prefix, int key)
int f = x_tab[prefix][key];
if (prefix)
/* prefix == 1 || prefix == 2 */
shf_puts(x_mapout(prefix == 1 ? CTRL('[') :
prefix == 2 ? CTRL('X') : 0), shl_stdout);
/* prefix == 1 || prefix == 2 || prefix == 3 */
shf_puts(x_mapout(prefix == 1 ? CTRL_BO :
prefix == 2 ? CTRL_X : 0), shl_stdout);
#ifdef MKSH_SMALL
shprintf("%s = ", x_mapout(key));
#else
@ -3331,17 +3330,17 @@ x_mode(bool onoff)
#endif
if (!edchars.erase)
edchars.erase = CTRL('H');
edchars.erase = CTRL_H;
if (!edchars.kill)
edchars.kill = CTRL('U');
edchars.kill = CTRL_U;
if (!edchars.intr)
edchars.intr = CTRL('C');
edchars.intr = CTRL_C;
if (!edchars.quit)
edchars.quit = CTRL('\\');
edchars.quit = CTRL_BK;
if (!edchars.eof)
edchars.eof = CTRL('D');
edchars.eof = CTRL_D;
if (!edchars.werase)
edchars.werase = CTRL('W');
edchars.werase = CTRL_W;
if (isedchar(edchars.erase)) {
bind_if_not_bound(0, edchars.erase, XFUNC_del_back);
@ -3401,11 +3400,10 @@ static void ed_mov_opt(int, char *);
static int expand_word(int);
static int complete_word(int, int);
static int print_expansions(struct edstate *, int);
#define char_len(c) ((ISCTRL((unsigned char)c) && \
/* but not C1 */ (unsigned char)c < 0x80) ? 2 : 1)
static void vi_error(void);
static void vi_macro_reset(void);
static int x_vi_putbuf(const char *, size_t);
#define char_len(c) (ksh_isctrl(c) ? 2 : 1)
#define vC 0x01 /* a valid command that isn't a vM, vE, vU */
#define vM 0x02 /* movement command (h, l, etc.) */
@ -3653,7 +3651,7 @@ vi_hook(int ch)
default: ch = 0; goto vi_insert_failed;
}
if (insert != 0) {
if (ch == CTRL('v')) {
if (ch == CTRL_V) {
state = VLIT;
ch = '^';
}
@ -3767,7 +3765,7 @@ vi_hook(int ch)
break;
case VXCH:
if (ch == CTRL('['))
if (ch == CTRL_BO)
state = VNORMAL;
else {
curcmd[cmdlen++] = ch;
@ -3776,7 +3774,7 @@ vi_hook(int ch)
break;
case VSEARCH:
if (ctype(ch, C_CR | C_LF) /* || ch == CTRL('[') */ ) {
if (ctype(ch, C_CR | C_LF) /* || ch == CTRL_BO */ ) {
restore_cbuf();
/* Repeat last search? */
if (srchlen == 0) {
@ -3791,7 +3789,7 @@ vi_hook(int ch)
memcpy(srchpat, locpat, srchlen + 1);
}
state = VCMD;
} else if (isched(ch, edchars.erase) || ch == CTRL('h')) {
} else if (isched(ch, edchars.erase) || ch == CTRL_H) {
if (srchlen != 0) {
srchlen--;
vs->linelen -= char_len(locpat[srchlen]);
@ -3832,12 +3830,12 @@ vi_hook(int ch)
vi_error();
else {
locpat[srchlen++] = ch;
if (ISCTRL(ch) && /* but not C1 */ ch < 0x80) {
if (ksh_isctrl(ch)) {
if ((size_t)vs->linelen + 2 >
(size_t)vs->cbufsize)
vi_error();
vs->cbuf[vs->linelen++] = '^';
vs->cbuf[vs->linelen++] = UNCTRL(ch);
vs->cbuf[vs->linelen++] = ksh_unctrl(ch);
} else {
if (vs->linelen >= vs->cbufsize)
vi_error();
@ -3949,7 +3947,7 @@ nextstate(int ch)
return (VXCH);
else if (ch == '.')
return (VREDO);
else if (ch == CTRL('v'))
else if (ch == CTRL_V)
return (VVERSION);
else if (is_cmd(ch))
return (VCMD);
@ -3962,7 +3960,7 @@ vi_insert(int ch)
{
int tcursor;
if (isched(ch, edchars.erase) || ch == CTRL('h')) {
if (isched(ch, edchars.erase) || ch == CTRL_H) {
if (insert == REPLACE) {
if (vs->cursor == undo->cursor) {
vi_error();
@ -4019,7 +4017,7 @@ vi_insert(int ch)
* buffer (if user inserts & deletes char, ibuf gets trashed and
* we don't want to use it)
*/
if (first_insert && ch != CTRL('['))
if (first_insert && ch != CTRL_BO)
saved_inslen = 0;
switch (ch) {
case '\0':
@ -4029,7 +4027,7 @@ vi_insert(int ch)
case '\n':
return (1);
case CTRL('['):
case CTRL_BO:
expanded = NONE;
if (first_insert) {
first_insert = false;
@ -4046,19 +4044,19 @@ vi_insert(int ch)
return (redo_insert(lastac - 1));
/* { start nonstandard vi commands */
case CTRL('x'):
case CTRL_X:
expand_word(0);
break;
case CTRL('f'):
case CTRL_F:
complete_word(0, 0);
break;
case CTRL('e'):
case CTRL_E:
print_expansions(vs, 0);
break;
case CTRL('i'):
case CTRL_I:
if (Flag(FVITABCOMPLETE)) {
complete_word(0, 0);
break;
@ -4113,8 +4111,8 @@ vi_cmd(int argcnt, const char *cmd)
}
switch (*cmd) {
case CTRL('l'):
case CTRL('r'):
case CTRL_L:
case CTRL_R:
redraw_line(true);
break;
@ -4302,7 +4300,7 @@ vi_cmd(int argcnt, const char *cmd)
case 'j':
case '+':
case CTRL('n'):
case CTRL_N:
if (grabhist(modified, hnum + argcnt) < 0)
return (-1);
else {
@ -4313,7 +4311,7 @@ vi_cmd(int argcnt, const char *cmd)
case 'k':
case '-':
case CTRL('p'):
case CTRL_P:
if (grabhist(modified, hnum - argcnt) < 0)
return (-1);
else {
@ -4546,27 +4544,27 @@ vi_cmd(int argcnt, const char *cmd)
/* AT&T ksh */
case '=':
/* Nonstandard vi/ksh */
case CTRL('e'):
case CTRL_E:
print_expansions(vs, 1);
break;
/* Nonstandard vi/ksh */
case CTRL('i'):
case CTRL_I:
if (!Flag(FVITABCOMPLETE))
return (-1);
complete_word(1, argcnt);
break;
/* some annoying AT&T kshs */
case CTRL('['):
case CTRL_BO:
if (!Flag(FVIESCCOMPLETE))
return (-1);
/* FALLTHROUGH */
/* AT&T ksh */
case '\\':
/* Nonstandard vi/ksh */
case CTRL('f'):
case CTRL_F:
complete_word(1, argcnt);
break;
@ -4574,7 +4572,7 @@ vi_cmd(int argcnt, const char *cmd)
/* AT&T ksh */
case '*':
/* Nonstandard vi/ksh */
case CTRL('x'):
case CTRL_X:
expand_word(1);
break;
@ -4652,7 +4650,7 @@ domove(int argcnt, const char *cmd, int sub)
break;
case 'h':
case CTRL('h'):
case CTRL_H:
if (!sub && vs->cursor == 0)
return (-1);
ncursor = vs->cursor - argcnt;
@ -5188,10 +5186,10 @@ display(char *wb1, char *wb2, int leftside)
*twb1++ = ' ';
} while (++col < winwidth && (col & 7) != 0);
else if (col < winwidth) {
if (ISCTRL(ch) && /* but not C1 */ ch < 0x80) {
if (ksh_isctrl(ch)) {
*twb1++ = '^';
if (++col < winwidth) {
*twb1++ = UNCTRL(ch);
*twb1++ = ksh_unctrl(ch);
col++;
}
} else {
@ -5467,9 +5465,9 @@ print_expansions(struct edstate *est, int cmd MKSH_A_UNUSED)
static void
x_vi_zotc(int c)
{
if (ISCTRL(c)) {
if (ksh_isctrl(c)) {
x_putc('^');
c = UNCTRL(c);
c = ksh_unctrl(c);
}
x_putc(c);
}

10
misc.c
View File

@ -32,7 +32,7 @@
#include <grp.h>
#endif
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.266 2017/04/28 02:24:57 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/misc.c,v 1.267 2017/04/28 03:28:18 tg Exp $");
#define KSH_CHVT_FLAG
#ifdef MKSH_SMALL
@ -1098,7 +1098,7 @@ print_value_quoted(struct shf *shf, const char *s)
bool inquote = true;
/* first, check whether any quotes are needed */
while ((c = *p++) >= 32)
while (asc(c = *p++) >= 32)
if (ctype(c, C_QUOTE | C_SPC))
inquote = false;
@ -1137,6 +1137,7 @@ print_value_quoted(struct shf *shf, const char *s)
shf_putc('$', shf);
shf_putc('\'', shf);
while ((c = *p) != 0) {
#ifndef MKSH_EBCDIC
if (c >= 0xC2) {
n = utf_mbtowc(&wc, (const char *)p);
if (n != (size_t)-1) {
@ -1145,6 +1146,7 @@ print_value_quoted(struct shf *shf, const char *s)
continue;
}
}
#endif
++p;
switch (c) {
/* see unbksl() in this file for comments */
@ -1187,7 +1189,7 @@ print_value_quoted(struct shf *shf, const char *s)
/* FALLTHROUGH */
default:
#ifdef MKSH_EBCDIC
if (c < 64 || c == 0xFF)
if (ksh_isctrl(c))
#else
if (c < 32 || c > 0x7E)
#endif
@ -2151,7 +2153,7 @@ unbksl(bool cstyle, int (*fg)(void), void (*fp)(int))
if (!cstyle)
goto unknown_escape;
c = (*fg)();
wc = CTRL(c);
wc = ksh_toctrl(c);
break;
case 'E':
case 'e':

80
sh.h
View File

@ -175,7 +175,7 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.824 2017/04/28 02:40:25 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.825 2017/04/28 03:28:18 tg Exp $");
#endif
#define MKSH_VERSION "R55 2017/04/27"
@ -1476,12 +1476,15 @@ extern void ebcdic_init(void);
#define asc(c) ((unsigned int)ebcdic_map[(unsigned char)(c)])
#define rtt2asc(c) ebcdic_rtt_toascii[(unsigned char)(c)]
#define asc2rtt(c) ebcdic_rtt_fromascii[(unsigned char)(c)]
/* control character foo */
#define ksh_isctrl(c) (ord(c) < 0x40 || ord(c) == 0xFF)
/* case-independent char comparison */
#define ksh_eq(c,u,l) (ord(c) == ord(u) || ord(c) == ord(l))
#else
#define asc(c) ord(c)
#define rtt2asc(c) ((unsigned char)(c))
#define asc2rtt(c) ((unsigned char)(c))
#define ksh_isctrl(c) (((c) & 0x7F) < 0x20 || (c) == 0x7F)
#define ksh_eq(c,u,l) ((ord(c) | 0x20) == ord(l))
#endif
/* new fast character classes */
@ -1495,6 +1498,8 @@ extern void ebcdic_init(void);
#define ksh_numdig(c) (ord(c) - ord('0'))
#define ksh_numuc(c) (asc(c) - asc('A'))
#define ksh_numlc(c) (asc(c) - asc('a'))
#define ksh_toctrl(c) asc2rtt(ord(c) == ord('?') ? 0x7F : rtt2asc(c) & 0x9F)
#define ksh_unctrl(c) asc2rtt(rtt2asc(c) ^ 0x40U)
/* Argument parsing for built-in commands and getopts command */
@ -2167,10 +2172,75 @@ typedef union {
#define HERES 10 /* max number of << in line */
#undef CTRL
#define CTRL(x) ((x) == '?' ? 0x7F : (x) & 0x1F) /* ASCII */
#define UNCTRL(x) ((x) ^ 0x40) /* ASCII */
#define ISCTRL(x) (((signed char)((uint8_t)(x) + 1)) < 33)
#ifdef MKSH_EBCDIC
#define CTRL_AT 0x00
#define CTRL_A 0x01
#define CTRL_B 0x02
#define CTRL_C 0x03
#define CTRL_D 0x37
#define CTRL_E 0x2D
#define CTRL_F 0x2E
#define CTRL_G 0x2F
#define CTRL_H 0x16
#define CTRL_I 0x05
#define CTRL_J 0x15
#define CTRL_K 0x0B
#define CTRL_L 0x0C
#define CTRL_M 0x0D
#define CTRL_N 0x0E
#define CTRL_O 0x0F
#define CTRL_P 0x10
#define CTRL_Q 0x11
#define CTRL_R 0x12
#define CTRL_S 0x13
#define CTRL_T 0x3C
#define CTRL_U 0x3D
#define CTRL_V 0x32
#define CTRL_W 0x26
#define CTRL_X 0x18
#define CTRL_Y 0x19
#define CTRL_Z 0x3F
#define CTRL_BO 0x27
#define CTRL_BK 0x1C
#define CTRL_BC 0x1D
#define CTRL_CA 0x1E
#define CTRL_US 0x1F
#define CTRL_QM 0x07
#else
#define CTRL_AT 0x00
#define CTRL_A 0x01
#define CTRL_B 0x02
#define CTRL_C 0x03
#define CTRL_D 0x04
#define CTRL_E 0x05
#define CTRL_F 0x06
#define CTRL_G 0x07
#define CTRL_H 0x08
#define CTRL_I 0x09
#define CTRL_J 0x0A
#define CTRL_K 0x0B
#define CTRL_L 0x0C
#define CTRL_M 0x0D
#define CTRL_N 0x0E
#define CTRL_O 0x0F
#define CTRL_P 0x10
#define CTRL_Q 0x11
#define CTRL_R 0x12
#define CTRL_S 0x13
#define CTRL_T 0x14
#define CTRL_U 0x15
#define CTRL_V 0x16
#define CTRL_W 0x17
#define CTRL_X 0x18
#define CTRL_Y 0x19
#define CTRL_Z 0x1A
#define CTRL_BO 0x1B
#define CTRL_BK 0x1C
#define CTRL_BC 0x1D
#define CTRL_CA 0x1E
#define CTRL_US 0x1F
#define CTRL_QM 0x7F
#endif
#define IDENT 64

14
tree.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.90 2017/04/28 00:38:33 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.91 2017/04/28 03:28:19 tg Exp $");
#define INDENT 8
@ -798,13 +798,13 @@ vistree(char *dst, size_t sz, struct op *t)
if (--sz == 0 || (c = (unsigned char)(*cp++)) == 0)
/* NUL or not enough free space */
goto vist_out;
if (ISCTRL(c & 0x7F)) {
if (ksh_isctrl(c)) {
/* C0 or C1 control character or DEL */
if (--sz == 0)
/* not enough free space for two chars */
goto vist_out;
*dst++ = (c & 0x80) ? '$' : '^';
c = UNCTRL(c & 0x7F);
*dst++ = '^';
c = ksh_unctrl(c);
} else if (UTFMODE && c > 0x7F) {
/* better not try to display broken multibyte chars */
/* also go easy on the Unicode: no U+FFFD here */
@ -822,10 +822,10 @@ vistree(char *dst, size_t sz, struct op *t)
void
dumpchar(struct shf *shf, int c)
{
if (ISCTRL(c & 0x7F)) {
if (ksh_isctrl(c)) {
/* C0 or C1 control character or DEL */
shf_putc((c & 0x80) ? '$' : '^', shf);
c = UNCTRL(c & 0x7F);
shf_putc('^', shf);
c = ksh_unctrl(c);
}
shf_putc(c, shf);
}