Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/vt/vt_buf.c
Show First 20 Lines • Show All 740 Lines • ▼ Show 20 Lines | vtbuf_get_marked_len(struct vt_buf *vb) | ||||
si = s.tp_row * vb->vb_scr_size.tp_col + s.tp_col; | si = s.tp_row * vb->vb_scr_size.tp_col + s.tp_col; | ||||
ei = e.tp_row * vb->vb_scr_size.tp_col + e.tp_col; | ei = e.tp_row * vb->vb_scr_size.tp_col + e.tp_col; | ||||
/* Number symbols and number of rows to inject \r */ | /* Number symbols and number of rows to inject \r */ | ||||
sz = ei - si + (e.tp_row - s.tp_row); | sz = ei - si + (e.tp_row - s.tp_row); | ||||
return (sz * sizeof(term_char_t)); | return (sz * sizeof(term_char_t)); | ||||
} | } | ||||
#endif | |||||
markj: Is part of the patch missing? | |||||
static bool | static bool | ||||
tchar_is_word_separator(term_char_t ch) | tchar_is_word_separator(term_char_t ch) | ||||
{ | { | ||||
/* List of unicode word separator characters: */ | /* List of unicode word separator characters: */ | ||||
switch (TCHAR_CHARACTER(ch)) { | switch (TCHAR_CHARACTER(ch)) { | ||||
case 0x0020: /* SPACE */ | case 0x0020: /* SPACE */ | ||||
case 0x180E: /* MONGOLIAN VOWEL SEPARATOR */ | case 0x180E: /* MONGOLIAN VOWEL SEPARATOR */ | ||||
case 0x2002: /* EN SPACE (nut) */ | case 0x2002: /* EN SPACE (nut) */ | ||||
case 0x2003: /* EM SPACE (mutton) */ | case 0x2003: /* EM SPACE (mutton) */ | ||||
case 0x2004: /* THREE-PER-EM SPACE (thick space) */ | case 0x2004: /* THREE-PER-EM SPACE (thick space) */ | ||||
case 0x2005: /* FOUR-PER-EM SPACE (mid space) */ | case 0x2005: /* FOUR-PER-EM SPACE (mid space) */ | ||||
case 0x2006: /* SIX-PER-EM SPACE */ | case 0x2006: /* SIX-PER-EM SPACE */ | ||||
case 0x2008: /* PUNCTUATION SPACE */ | case 0x2008: /* PUNCTUATION SPACE */ | ||||
case 0x2009: /* THIN SPACE */ | case 0x2009: /* THIN SPACE */ | ||||
case 0x200A: /* HAIR SPACE */ | case 0x200A: /* HAIR SPACE */ | ||||
case 0x200B: /* ZERO WIDTH SPACE */ | case 0x200B: /* ZERO WIDTH SPACE */ | ||||
case 0x3000: /* IDEOGRAPHIC SPACE */ | case 0x3000: /* IDEOGRAPHIC SPACE */ | ||||
return (true); | return (true); | ||||
default: | default: | ||||
return (false); | return (false); | ||||
} | } | ||||
} | } | ||||
static bool | |||||
vtbuf_extract_utf8(term_char_t ch, char *buffer, size_t *ppos, size_t size) | |||||
{ | |||||
char temp[32]; | |||||
size_t len; | |||||
ch = TCHAR_CHARACTER(ch); | |||||
switch (ch) { | |||||
case 'a' ... 'z': | |||||
case 'A' ... 'Z': | |||||
case '0' ... '9': | |||||
temp[0] = (char)ch; | |||||
temp[1] = 0; | |||||
break; | |||||
case '~': | |||||
strlcpy(temp, " tilde ", sizeof(temp)); | |||||
break; | |||||
case '#': | |||||
strlcpy(temp, " hash ", sizeof(temp)); | |||||
break; | |||||
case '+': | |||||
strlcpy(temp, " plus ", sizeof(temp)); | |||||
break; | |||||
case '-': | |||||
strlcpy(temp, " minus ", sizeof(temp)); | |||||
break; | |||||
case '_': | |||||
strlcpy(temp, " underscore ", sizeof(temp)); | |||||
break; | |||||
case '*': | |||||
strlcpy(temp, " multiply ", sizeof(temp)); | |||||
break; | |||||
case '/': | |||||
strlcpy(temp, " divide ", sizeof(temp)); | |||||
break; | |||||
case '\\': | |||||
strlcpy(temp, " backslash ", sizeof(temp)); | |||||
break; | |||||
case '=': | |||||
strlcpy(temp, " equal ", sizeof(temp)); | |||||
break; | |||||
case '@': | |||||
strlcpy(temp, " at ", sizeof(temp)); | |||||
break; | |||||
case '^': | |||||
strlcpy(temp, " xor ", sizeof(temp)); | |||||
break; | |||||
case '|': | |||||
strlcpy(temp, " pipe ", sizeof(temp)); | |||||
break; | |||||
case '&': | |||||
strlcpy(temp, " and ", sizeof(temp)); | |||||
break; | |||||
case '(': | |||||
strlcpy(temp, " opening parenthesis ", sizeof(temp)); | |||||
break; | |||||
case ')': | |||||
strlcpy(temp, " closing parenthesis ", sizeof(temp)); | |||||
break; | |||||
case '[': | |||||
strlcpy(temp, " opening bracket ", sizeof(temp)); | |||||
break; | |||||
case ']': | |||||
strlcpy(temp, " closing bracket ", sizeof(temp)); | |||||
break; | |||||
case '{': | |||||
strlcpy(temp, " opening curlybracket ", sizeof(temp)); | |||||
break; | |||||
case '}': | |||||
strlcpy(temp, " closing curlybracket ", sizeof(temp)); | |||||
break; | |||||
case '.': | |||||
strlcpy(temp, " period ", sizeof(temp)); | |||||
break; | |||||
case ',': | |||||
strlcpy(temp, " comma ", sizeof(temp)); | |||||
break; | |||||
case ':': | |||||
strlcpy(temp, " colon ", sizeof(temp)); | |||||
break; | |||||
case ';': | |||||
strlcpy(temp, " semicolon ", sizeof(temp)); | |||||
break; | |||||
case '!': | |||||
strlcpy(temp, " not ", sizeof(temp)); | |||||
break; | |||||
case '$': | |||||
strlcpy(temp, " dollar ", sizeof(temp)); | |||||
break; | |||||
case '?': | |||||
strlcpy(temp, " questionmark ", sizeof(temp)); | |||||
break; | |||||
case '>': | |||||
strlcpy(temp, " greaterthan ", sizeof(temp)); | |||||
break; | |||||
case '<': | |||||
strlcpy(temp, " lessthan ", sizeof(temp)); | |||||
break; | |||||
case '"': | |||||
strlcpy(temp, " quote ", sizeof(temp)); | |||||
break; | |||||
case '\'': | |||||
strlcpy(temp, " apostrophe ", sizeof(temp)); | |||||
break; | |||||
case '%': | |||||
strlcpy(temp, " percent ", sizeof(temp)); | |||||
break; | |||||
default: | |||||
if (tchar_is_word_separator(ch)) { | |||||
temp[0] = ' '; | |||||
temp[1] = 0; | |||||
} else { | |||||
snprintf(temp, sizeof(temp), " uc %u ", (uint32_t)ch); | |||||
} | |||||
break; | |||||
} | |||||
len = strlen(temp) + 1; | |||||
if (*ppos + len > size) | |||||
return (false); | |||||
memcpy(buffer + *ppos, temp, len - 1); | |||||
*ppos += len - 1; | |||||
return (true); | |||||
} | |||||
static bool | |||||
tchar_is_extended_word_separator(term_char_t ch) | |||||
{ | |||||
if (tchar_is_word_separator(ch)) { | |||||
return (true); | |||||
} else { | |||||
char temp[2]; | |||||
size_t pos = 0; | |||||
return (!vtbuf_extract_utf8(ch, temp, &pos, sizeof(temp))); | |||||
} | |||||
} | |||||
static const char vt_accessibility_overflow[] = { "Line cannot be spoken" }; | |||||
void | |||||
vtbuf_extract_accessibility(char *buffer, size_t lines, size_t sz) | |||||
{ | |||||
Not Done Inline ActionsThe lines here are too long. Maybe it's a sign that the loop body should be split into a separate function? markj: The lines here are too long. Maybe it's a sign that the loop body should be split into a… | |||||
struct vt_device *vd; | |||||
struct vt_window *vw; | |||||
struct vt_buf *vb; | |||||
term_pos_t max; | |||||
term_char_t ch; | |||||
size_t pos; | |||||
size_t last_sep_off; | |||||
size_t last_line_off; | |||||
int last_sep_col; | |||||
int c; | |||||
int i; | |||||
int r; | |||||
MPASS(sz != 0); | |||||
MPASS(lines != 0); | |||||
vd = main_vd; | |||||
vw = vd->vd_curwindow; | |||||
vb = &vw->vw_buf; | |||||
max = vb->vb_scr_size; | |||||
pos = 0; | |||||
VTBUF_LOCK(vb); | |||||
for (i = 0; lines != 0 && i != max.tp_row; i++) { | |||||
/* Get real row number in VT buffer. */ | |||||
r = (vb->vb_roffset + i) % vb->vb_history_size; | |||||
/* Find first character, get whole word, if any. */ | |||||
for (c = 0; c != max.tp_col; c++) { | |||||
ch = vb->vb_rows[r][c]; | |||||
if (TCHAR_ACCESSIBILITY(ch) != 0 || | |||||
TCHAR_CHARACTER(ch) == 0) | |||||
continue; | |||||
if (tchar_is_extended_word_separator(ch)) | |||||
break; | |||||
/* Go back a bit to get context, if any. */ | |||||
while (c != 0) { | |||||
c--; | |||||
ch = vb->vb_rows[r][c]; | |||||
if (TCHAR_CHARACTER(ch) == 0) | |||||
continue; | |||||
if (tchar_is_extended_word_separator(ch)) | |||||
break; | |||||
} | |||||
break; | |||||
} | |||||
if (c == max.tp_col) | |||||
continue; | |||||
lines--; | |||||
last_sep_col = c; | |||||
last_sep_off = pos; | |||||
last_line_off = pos; | |||||
/* Try to output line. */ | |||||
for( ; c != max.tp_col; c++) { | |||||
ch = vb->vb_rows[r][c]; | |||||
if (TCHAR_CHARACTER(ch) == 0) | |||||
continue; | |||||
if (tchar_is_extended_word_separator(ch)) { | |||||
if (vtbuf_extract_utf8(ch, buffer, &pos, sz) == false) | |||||
break; | |||||
/* Keep track of sensible stop locations. */ | |||||
last_sep_col = c + 1; | |||||
last_sep_off = pos; | |||||
} else { | |||||
if (vtbuf_extract_utf8(ch, buffer, &pos, sz) == false) | |||||
break; | |||||
} | |||||
} | |||||
/* Check if buffer is full (whole line was not consumed). */ | |||||
if (c != max.tp_col) { | |||||
/* Check if this is the first line. */ | |||||
if (last_line_off == 0) { | |||||
/* XXX Pretend line was consumed. */ | |||||
pos = last_line_off; | |||||
c = max.tp_col; | |||||
for (size_t i = 0; vt_accessibility_overflow[i]; i++) { | |||||
if (vtbuf_extract_utf8(vt_accessibility_overflow[i], | |||||
buffer, &pos, sz) == false) | |||||
break; | |||||
} | |||||
} else { | |||||
/* Stop at last separator, if any. */ | |||||
pos = last_sep_off; | |||||
c = last_sep_col; | |||||
} | |||||
/* Don't output this part again. */ | |||||
while (c--) | |||||
vb->vb_rows[r][c] |= TACCESSIBILITY; | |||||
break; | |||||
} else { | |||||
/* Don't output this line again. */ | |||||
while (c--) | |||||
vb->vb_rows[r][c] |= TACCESSIBILITY; | |||||
/* Remove trailing white space. */ | |||||
while (pos != last_line_off && buffer[pos - 1] == ' ') | |||||
pos--; | |||||
if (pos == last_line_off) { | |||||
/* Grab another line, this one is empty. */ | |||||
lines++; | |||||
} else { | |||||
/* Insert a word separator, just in case. */ | |||||
if (vtbuf_extract_utf8(' ', buffer, &pos, sz)) | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
VTBUF_UNLOCK(vb); | |||||
/* Remove trailing white space from last line. */ | |||||
while (pos != 0 && buffer[pos - 1] == ' ') | |||||
pos--; | |||||
/* Put the terminating character there. */ | |||||
buffer[pos] = 0; | |||||
} | |||||
#ifndef SC_NO_CUTPASTE | |||||
void | void | ||||
vtbuf_extract_marked(struct vt_buf *vb, term_char_t *buf, int sz) | vtbuf_extract_marked(struct vt_buf *vb, term_char_t *buf, int sz) | ||||
{ | { | ||||
int i, j, r, c, cs, ce; | int i, j, r, c, cs, ce; | ||||
term_pos_t s, e; | term_pos_t s, e; | ||||
/* Swap according to window coordinates. */ | /* Swap according to window coordinates. */ | ||||
if (POS_INDEX(vtbuf_htw(vb, vb->vb_mark_start.tp_row), | if (POS_INDEX(vtbuf_htw(vb, vb->vb_mark_start.tp_row), | ||||
▲ Show 20 Lines • Show All 145 Lines • Show Last 20 Lines |
Is part of the patch missing?