mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Add line-length limit feature in StripCtrlChars.
Now it can optionally check that output lines don't go beyond a certain length (measured in terminal columns, via wcwidth, rather than bytes or characters). In this mode, lines are prefixed with a distinctive character (namely '|'), and if a line is too long, then it is broken and the continuation line gets a different prefix ('>'). When StripCtrlChars is targeting a terminal, it asks the terminal to call wcwidth on its behalf, so it can be sure to use the same idea as the real terminal about which characters are wide (i.e. depending on the configuration of ambiguous characters). This mode isn't yet used anywhere.
This commit is contained in:
parent
da1c8f15b1
commit
3936616feb
2
Recipe
2
Recipe
@ -283,7 +283,7 @@ SFTP = sftp sftpcommon logging cmdline
|
||||
|
||||
# Miscellaneous objects appearing in all the utilities, or all the
|
||||
# network ones, or the Unix or Windows subsets of those in turn.
|
||||
MISC = misc utils marshal memory stripctrl
|
||||
MISC = misc utils marshal memory stripctrl wcwidth
|
||||
MISCNETCOMMON = timing callback MISC version tree234 CONF
|
||||
MISCNET = MISCNETCOMMON be_misc settings proxy
|
||||
WINMISC = MISCNET winstore winnet winhandl cmdline windefs winmisc winproxy
|
||||
|
1
misc.h
1
misc.h
@ -387,6 +387,7 @@ StripCtrlChars *stripctrl_new_term_fn(
|
||||
void stripctrl_retarget(StripCtrlChars *sccpub, BinarySink *new_bs_out);
|
||||
void stripctrl_reset(StripCtrlChars *sccpub);
|
||||
void stripctrl_free(StripCtrlChars *sanpub);
|
||||
void stripctrl_enable_line_limiting(StripCtrlChars *sccpub);
|
||||
char *stripctrl_string_ptrlen(StripCtrlChars *sccpub, ptrlen str);
|
||||
static inline char *stripctrl_string(StripCtrlChars *sccpub, const char *str)
|
||||
{
|
||||
|
55
stripctrl.c
55
stripctrl.c
@ -17,6 +17,7 @@
|
||||
#include "marshal.h"
|
||||
|
||||
#define SCC_BUFSIZE 64
|
||||
#define LINE_LIMIT 77
|
||||
|
||||
typedef struct StripCtrlCharsImpl StripCtrlCharsImpl;
|
||||
struct StripCtrlCharsImpl {
|
||||
@ -33,6 +34,10 @@ struct StripCtrlCharsImpl {
|
||||
struct term_utf8_decode utf8;
|
||||
unsigned long (*translate)(Terminal *, term_utf8_decode *, unsigned char);
|
||||
|
||||
bool line_limit;
|
||||
bool line_start;
|
||||
size_t line_chars_remaining;
|
||||
|
||||
BinarySink *bs_out;
|
||||
|
||||
StripCtrlChars public;
|
||||
@ -98,6 +103,11 @@ void stripctrl_reset(StripCtrlChars *sccpub)
|
||||
memset(&scc->utf8, 0, sizeof(scc->utf8));
|
||||
memset(&scc->mbs_in, 0, sizeof(scc->mbs_in));
|
||||
memset(&scc->mbs_out, 0, sizeof(scc->mbs_out));
|
||||
|
||||
/*
|
||||
* Also, reset the line-limiting system to its starting state.
|
||||
*/
|
||||
scc->line_start = true;
|
||||
}
|
||||
|
||||
void stripctrl_free(StripCtrlChars *sccpub)
|
||||
@ -108,11 +118,45 @@ void stripctrl_free(StripCtrlChars *sccpub)
|
||||
sfree(scc);
|
||||
}
|
||||
|
||||
void stripctrl_enable_line_limiting(StripCtrlChars *sccpub)
|
||||
{
|
||||
StripCtrlCharsImpl *scc =
|
||||
container_of(sccpub, StripCtrlCharsImpl, public);
|
||||
scc->line_limit = true;
|
||||
scc->line_start = true;
|
||||
}
|
||||
|
||||
static inline bool stripctrl_ctrlchar_ok(StripCtrlCharsImpl *scc, wchar_t wc)
|
||||
{
|
||||
return wc == L'\n' || (wc == L'\r' && scc->permit_cr);
|
||||
}
|
||||
|
||||
static inline void stripctrl_check_line_limit(
|
||||
StripCtrlCharsImpl *scc, wchar_t wc, size_t width)
|
||||
{
|
||||
if (!scc->line_limit)
|
||||
return; /* nothing to do */
|
||||
|
||||
if (scc->line_start) {
|
||||
put_datapl(scc->bs_out, PTRLEN_LITERAL("| "));
|
||||
scc->line_start = false;
|
||||
scc->line_chars_remaining = LINE_LIMIT;
|
||||
}
|
||||
|
||||
if (wc == '\n') {
|
||||
scc->line_start = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (scc->line_chars_remaining < width) {
|
||||
put_datapl(scc->bs_out, PTRLEN_LITERAL("\r\n> "));
|
||||
scc->line_chars_remaining = LINE_LIMIT;
|
||||
}
|
||||
|
||||
assert(width <= scc->line_chars_remaining);
|
||||
scc->line_chars_remaining -= width;
|
||||
}
|
||||
|
||||
static inline void stripctrl_locale_put_wc(StripCtrlCharsImpl *scc, wchar_t wc)
|
||||
{
|
||||
if (iswprint(wc) || stripctrl_ctrlchar_ok(scc, wc)) {
|
||||
@ -124,6 +168,8 @@ static inline void stripctrl_locale_put_wc(StripCtrlCharsImpl *scc, wchar_t wc)
|
||||
return;
|
||||
}
|
||||
|
||||
stripctrl_check_line_limit(scc, wc, mk_wcwidth(wc));
|
||||
|
||||
char outbuf[MB_LEN_MAX];
|
||||
size_t produced = wcrtomb(outbuf, wc, &scc->mbs_out);
|
||||
if (produced > 0)
|
||||
@ -133,6 +179,8 @@ static inline void stripctrl_locale_put_wc(StripCtrlCharsImpl *scc, wchar_t wc)
|
||||
static inline void stripctrl_term_put_wc(
|
||||
StripCtrlCharsImpl *scc, unsigned long wc)
|
||||
{
|
||||
ptrlen prefix = PTRLEN_LITERAL("");
|
||||
|
||||
if (!(wc & ~0x9F)) {
|
||||
/* This is something the terminal interprets as a control
|
||||
* character. */
|
||||
@ -148,10 +196,15 @@ static inline void stripctrl_term_put_wc(
|
||||
* generally be in the ONLCR mode where it assumes that
|
||||
* internally, and any \r on input has been stripped
|
||||
* out. */
|
||||
put_datapl(scc->bs_out, PTRLEN_LITERAL("\r"));
|
||||
prefix = PTRLEN_LITERAL("\r");
|
||||
}
|
||||
}
|
||||
|
||||
stripctrl_check_line_limit(scc, wc, term_char_width(scc->term, wc));
|
||||
|
||||
if (prefix.len)
|
||||
put_datapl(scc->bs_out, prefix);
|
||||
|
||||
char outbuf[6];
|
||||
size_t produced;
|
||||
|
||||
|
@ -2784,9 +2784,7 @@ static void term_display_graphic_char(Terminal *term, unsigned long c)
|
||||
if (DIRECT_CHAR(c))
|
||||
width = 1;
|
||||
if (!width)
|
||||
width = (term->cjk_ambig_wide ?
|
||||
mk_wcwidth_cjk((unsigned int) c) :
|
||||
mk_wcwidth((unsigned int) c));
|
||||
width = term_char_width(term, c);
|
||||
|
||||
if (term->wrapnext && term->wrap && width > 0) {
|
||||
cline->lattr |= LATTR_WRAPPED;
|
||||
|
@ -344,6 +344,10 @@ static inline bool in_utf(Terminal *term)
|
||||
|
||||
unsigned long term_translate(
|
||||
Terminal *term, term_utf8_decode *utf8, unsigned char c);
|
||||
static inline int term_char_width(Terminal *term, unsigned int c)
|
||||
{
|
||||
return term->cjk_ambig_wide ? mk_wcwidth_cjk(c) : mk_wcwidth(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* UCSINCOMPLETE is returned from term_translate if it's successfully
|
||||
|
Loading…
Reference in New Issue
Block a user