| @@ -1,32 +1,32 @@ | | | @@ -1,32 +1,32 @@ |
1 | /* $NetBSD: v_txt.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */ | | 1 | /* $NetBSD: v_txt.c,v 1.5 2017/11/21 06:35:22 rin Exp $ */ |
2 | /*- | | 2 | /*- |
3 | * Copyright (c) 1993, 1994 | | 3 | * Copyright (c) 1993, 1994 |
4 | * The Regents of the University of California. All rights reserved. | | 4 | * The Regents of the University of California. All rights reserved. |
5 | * Copyright (c) 1992, 1993, 1994, 1995, 1996 | | 5 | * Copyright (c) 1992, 1993, 1994, 1995, 1996 |
6 | * Keith Bostic. All rights reserved. | | 6 | * Keith Bostic. All rights reserved. |
7 | * | | 7 | * |
8 | * See the LICENSE file for redistribution information. | | 8 | * See the LICENSE file for redistribution information. |
9 | */ | | 9 | */ |
10 | | | 10 | |
11 | #include "config.h" | | 11 | #include "config.h" |
12 | | | 12 | |
13 | #include <sys/cdefs.h> | | 13 | #include <sys/cdefs.h> |
14 | #if 0 | | 14 | #if 0 |
15 | #ifndef lint | | 15 | #ifndef lint |
16 | static const char sccsid[] = "Id: v_txt.c,v 10.108 2003/07/18 21:27:42 skimo Exp (Berkeley) Date: 2003/07/18 21:27:42 "; | | 16 | static const char sccsid[] = "Id: v_txt.c,v 10.108 2003/07/18 21:27:42 skimo Exp (Berkeley) Date: 2003/07/18 21:27:42 "; |
17 | #endif /* not lint */ | | 17 | #endif /* not lint */ |
18 | #else | | 18 | #else |
19 | __RCSID("$NetBSD: v_txt.c,v 1.4 2014/01/26 21:43:45 christos Exp $"); | | 19 | __RCSID("$NetBSD: v_txt.c,v 1.5 2017/11/21 06:35:22 rin Exp $"); |
20 | #endif | | 20 | #endif |
21 | | | 21 | |
22 | #include <sys/types.h> | | 22 | #include <sys/types.h> |
23 | #include <sys/queue.h> | | 23 | #include <sys/queue.h> |
24 | #include <sys/stat.h> | | 24 | #include <sys/stat.h> |
25 | #include <sys/time.h> | | 25 | #include <sys/time.h> |
26 | | | 26 | |
27 | #include <bitstring.h> | | 27 | #include <bitstring.h> |
28 | #include <ctype.h> | | 28 | #include <ctype.h> |
29 | #include <errno.h> | | 29 | #include <errno.h> |
30 | #include <limits.h> | | 30 | #include <limits.h> |
31 | #include <stdio.h> | | 31 | #include <stdio.h> |
32 | #include <stdlib.h> | | 32 | #include <stdlib.h> |
| @@ -2265,51 +2265,63 @@ static int | | | @@ -2265,51 +2265,63 @@ static int |
2265 | txt_emark(SCR *sp, TEXT *tp, size_t cno) | | 2265 | txt_emark(SCR *sp, TEXT *tp, size_t cno) |
2266 | { | | 2266 | { |
2267 | CHAR_T ch; | | 2267 | CHAR_T ch; |
2268 | unsigned char *kp; | | 2268 | unsigned char *kp; |
2269 | size_t chlen, nlen, olen; | | 2269 | size_t chlen, nlen, olen; |
2270 | CHAR_T *p; | | 2270 | CHAR_T *p; |
2271 | | | 2271 | |
2272 | ch = CH_ENDMARK; | | 2272 | ch = CH_ENDMARK; |
2273 | | | 2273 | |
2274 | /* | | 2274 | /* |
2275 | * The end mark may not be the same size as the current character. | | 2275 | * The end mark may not be the same size as the current character. |
2276 | * Don't let the line shift. | | 2276 | * Don't let the line shift. |
2277 | */ | | 2277 | */ |
2278 | nlen = KEY_LEN(sp, ch); | | 2278 | nlen = KEY_COL(sp, ch); |
2279 | if (tp->lb[cno] == '\t') | | 2279 | if (tp->lb[cno] == '\t') |
2280 | (void)vs_columns(sp, tp->lb, tp->lno, &cno, &olen); | | 2280 | (void)vs_columns(sp, tp->lb, tp->lno, &cno, &olen); |
2281 | else | | 2281 | else |
2282 | olen = KEY_LEN(sp, tp->lb[cno]); | | 2282 | olen = KEY_COL(sp, tp->lb[cno]); |
2283 | | | 2283 | |
2284 | /* | | 2284 | /* |
2285 | * If the line got longer, well, it's weird, but it's easy. If | | 2285 | * If the line got longer, well, it's weird, but it's easy. If |
2286 | * it's the same length, it's easy. If it got shorter, we have | | 2286 | * it's the same length, it's easy. If it got shorter, we have |
2287 | * to fix it up. | | 2287 | * to fix it up. |
2288 | */ | | 2288 | */ |
2289 | if (olen > nlen) { | | 2289 | if (olen > nlen) { |
2290 | BINC_RETW(sp, tp->lb, tp->lb_len, tp->len + olen); | | 2290 | BINC_RETW(sp, tp->lb, tp->lb_len, tp->len + olen); |
2291 | chlen = olen - nlen; | | 2291 | chlen = olen - nlen; |
2292 | if (tp->insert != 0) | | 2292 | if (tp->insert != 0) |
2293 | MEMMOVEW(tp->lb + cno + 1 + chlen, | | 2293 | MEMMOVEW(tp->lb + cno + 1 + chlen, |
2294 | tp->lb + cno + 1, tp->insert); | | 2294 | tp->lb + cno + 1, tp->insert); |
2295 | | | 2295 | |
2296 | tp->len += chlen; | | 2296 | tp->len += chlen; |
2297 | tp->owrite += chlen; | | 2297 | tp->owrite += chlen; |
2298 | p = tp->lb + cno; | | 2298 | p = tp->lb + cno; |
2299 | if (tp->lb[cno] == '\t') | | 2299 | if (tp->lb[cno] == '\t') |
2300 | for (cno += chlen; chlen--;) | | 2300 | for (cno += chlen; chlen--;) |
2301 | *p++ = ' '; | | 2301 | *p++ = ' '; |
2302 | else | | 2302 | else if (INTISWIDE(tp->lb[cno])) { |
| | | 2303 | /* |
| | | 2304 | * Do not put the end mark on a part of a multi-width |
| | | 2305 | * char, which results in screen corruption. |
| | | 2306 | */ |
| | | 2307 | for (; chlen >= nlen; chlen -= nlen) { |
| | | 2308 | cno++; |
| | | 2309 | *p++ = ch; |
| | | 2310 | } |
| | | 2311 | /* Paranoia: nlen is usually 1. */ |
| | | 2312 | for (cno += chlen; chlen--;) |
| | | 2313 | *p++ = ' '; |
| | | 2314 | } else |
2303 | for (kp = KEY_NAME(sp, tp->lb[cno]), | | 2315 | for (kp = KEY_NAME(sp, tp->lb[cno]), |
2304 | cno += chlen; chlen--;) | | 2316 | cno += chlen; chlen--;) |
2305 | *p++ = *kp++; | | 2317 | *p++ = *kp++; |
2306 | } | | 2318 | } |
2307 | tp->lb[cno] = ch; | | 2319 | tp->lb[cno] = ch; |
2308 | return (vs_change(sp, tp->lno, LINE_RESET)); | | 2320 | return (vs_change(sp, tp->lno, LINE_RESET)); |
2309 | } | | 2321 | } |
2310 | | | 2322 | |
2311 | /* | | 2323 | /* |
2312 | * txt_err -- | | 2324 | * txt_err -- |
2313 | * Handle an error during input processing. | | 2325 | * Handle an error during input processing. |
2314 | */ | | 2326 | */ |
2315 | static void | | 2327 | static void |
| @@ -2447,61 +2459,66 @@ txt_insch(SCR *sp, TEXT *tp, ARG_CHAR_T | | | @@ -2447,61 +2459,66 @@ txt_insch(SCR *sp, TEXT *tp, ARG_CHAR_T |
2447 | cno = tp->cno; | | 2459 | cno = tp->cno; |
2448 | | | 2460 | |
2449 | /* | | 2461 | /* |
2450 | * If the old or new characters are tabs, then the length of the | | 2462 | * If the old or new characters are tabs, then the length of the |
2451 | * display depends on the character position in the display. We | | 2463 | * display depends on the character position in the display. We |
2452 | * don't even try to handle this here, just ask the screen. | | 2464 | * don't even try to handle this here, just ask the screen. |
2453 | */ | | 2465 | */ |
2454 | if (*chp == '\t') { | | 2466 | if (*chp == '\t') { |
2455 | savech = tp->lb[cno]; | | 2467 | savech = tp->lb[cno]; |
2456 | tp->lb[cno] = '\t'; | | 2468 | tp->lb[cno] = '\t'; |
2457 | (void)vs_columns(sp, tp->lb, tp->lno, &cno, &nlen); | | 2469 | (void)vs_columns(sp, tp->lb, tp->lno, &cno, &nlen); |
2458 | tp->lb[cno] = savech; | | 2470 | tp->lb[cno] = savech; |
2459 | } else | | 2471 | } else |
2460 | nlen = KEY_LEN(sp, *chp); | | 2472 | nlen = KEY_COL(sp, *chp); |
2461 | | | 2473 | |
2462 | /* | | 2474 | /* |
2463 | * Eat overwrite characters until we run out of them or we've | | 2475 | * Eat overwrite characters until we run out of them or we've |
2464 | * handled the length of the new character. If we only eat | | 2476 | * handled the length of the new character. If we only eat |
2465 | * part of an overwrite character, break it into its component | | 2477 | * part of an overwrite character, break it into its component |
2466 | * elements and display the remaining components. | | 2478 | * elements and display the remaining components. |
2467 | */ | | 2479 | */ |
2468 | for (copydown = 0; nlen != 0 && tp->owrite != 0;) { | | 2480 | for (copydown = 0; nlen != 0 && tp->owrite != 0;) { |
2469 | --tp->owrite; | | 2481 | --tp->owrite; |
2470 | | | 2482 | |
2471 | if (tp->lb[cno] == '\t') | | 2483 | if (tp->lb[cno] == '\t') |
2472 | (void)vs_columns(sp, | | 2484 | (void)vs_columns(sp, |
2473 | tp->lb, tp->lno, &cno, &olen); | | 2485 | tp->lb, tp->lno, &cno, &olen); |
2474 | else | | 2486 | else |
2475 | olen = KEY_LEN(sp, tp->lb[cno]); | | 2487 | olen = KEY_COL(sp, tp->lb[cno]); |
2476 | | | 2488 | |
2477 | if (olen == nlen) { | | 2489 | if (olen == nlen) { |
2478 | nlen = 0; | | 2490 | nlen = 0; |
2479 | break; | | 2491 | break; |
2480 | } | | 2492 | } |
2481 | if (olen < nlen) { | | 2493 | if (olen < nlen) { |
2482 | ++copydown; | | 2494 | ++copydown; |
2483 | nlen -= olen; | | 2495 | nlen -= olen; |
2484 | } else { | | 2496 | } else { |
2485 | BINC_RETW(sp, | | 2497 | BINC_RETW(sp, |
2486 | tp->lb, tp->lb_len, tp->len + olen); | | 2498 | tp->lb, tp->lb_len, tp->len + olen); |
2487 | chlen = olen - nlen; | | 2499 | chlen = olen - nlen; |
2488 | MEMMOVEW(tp->lb + cno + 1 + chlen, | | 2500 | MEMMOVEW(tp->lb + cno + 1 + chlen, |
2489 | tp->lb + cno + 1, | | 2501 | tp->lb + cno + 1, |
2490 | tp->owrite + tp->insert); | | 2502 | tp->owrite + tp->insert); |
2491 | | | 2503 | |
2492 | tp->len += chlen; | | 2504 | tp->len += chlen; |
2493 | tp->owrite += chlen; | | 2505 | tp->owrite += chlen; |
2494 | if (tp->lb[cno] == '\t') | | 2506 | /* |
| | | 2507 | * Do not rewrite a part of a multi-width char, |
| | | 2508 | * which results in screen corruption. |
| | | 2509 | */ |
| | | 2510 | if (tp->lb[cno] == '\t' |
| | | 2511 | || INTISWIDE(tp->lb[cno])) |
2495 | for (p = tp->lb + cno + 1; chlen--;) | | 2512 | for (p = tp->lb + cno + 1; chlen--;) |
2496 | *p++ = ' '; | | 2513 | *p++ = ' '; |
2497 | else | | 2514 | else |
2498 | for (kp = | | 2515 | for (kp = |
2499 | KEY_NAME(sp, tp->lb[cno]) + nlen, | | 2516 | KEY_NAME(sp, tp->lb[cno]) + nlen, |
2500 | p = tp->lb + cno + 1; chlen--;) | | 2517 | p = tp->lb + cno + 1; chlen--;) |
2501 | *p++ = *kp++; | | 2518 | *p++ = *kp++; |
2502 | nlen = 0; | | 2519 | nlen = 0; |
2503 | break; | | 2520 | break; |
2504 | } | | 2521 | } |
2505 | } | | 2522 | } |
2506 | | | 2523 | |
2507 | /* | | 2524 | /* |