1 /* vi:set ts=8 sts=4 sw=4: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 #include "vim.h" 11 12 #ifdef FEAT_LINEBREAK 13 static int win_chartabsize __ARGS((win_T *wp, char_u *p, colnr_T col)); 14 #endif 15 16 #ifdef FEAT_MBYTE 17 static int win_nolbr_chartabsize __ARGS((win_T *wp, char_u *s, colnr_T col, int *headp)); 18 #endif 19 20 static int nr2hex __ARGS((int c)); 21 22 static int chartab_initialized = FALSE; 23 24 /* b_chartab[] is an array of 32 bytes, each bit representing one of the 25 * characters 0-255. */ 26 #define SET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] |= (1 << ((c) & 0x7)) 27 #define RESET_CHARTAB(buf, c) (buf)->b_chartab[(unsigned)(c) >> 3] &= ~(1 << ((c) & 0x7)) 28 #define GET_CHARTAB(buf, c) ((buf)->b_chartab[(unsigned)(c) >> 3] & (1 << ((c) & 0x7))) 29 30 /* 31 * Fill chartab[]. Also fills curbuf->b_chartab[] with flags for keyword 32 * characters for current buffer. 33 * 34 * Depends on the option settings 'iskeyword', 'isident', 'isfname', 35 * 'isprint' and 'encoding'. 36 * 37 * The index in chartab[] depends on 'encoding': 38 * - For non-multi-byte index with the byte (same as the character). 39 * - For DBCS index with the first byte. 40 * - For UTF-8 index with the character (when first byte is up to 0x80 it is 41 * the same as the character, if the first byte is 0x80 and above it depends 42 * on further bytes). 43 * 44 * The contents of chartab[]: 45 * - The lower two bits, masked by CT_CELL_MASK, give the number of display 46 * cells the character occupies (1 or 2). Not valid for UTF-8 above 0x80. 47 * - CT_PRINT_CHAR bit is set when the character is printable (no need to 48 * translate the character before displaying it). Note that only DBCS 49 * characters can have 2 display cells and still be printable. 50 * - CT_FNAME_CHAR bit is set when the character can be in a file name. 51 * - CT_ID_CHAR bit is set when the character can be in an identifier. 52 * 53 * Return FAIL if 'iskeyword', 'isident', 'isfname' or 'isprint' option has an 54 * error, OK otherwise. 55 */ 56 int 57 init_chartab() 58 { 59 return buf_init_chartab(curbuf, TRUE); 60 } 61 62 int 63 buf_init_chartab(buf, global) 64 buf_T *buf; 65 int global; /* FALSE: only set buf->b_chartab[] */ 66 { 67 int c; 68 int c2; 69 char_u *p; 70 int i; 71 int tilde; 72 int do_isalpha; 73 74 if (global) 75 { 76 /* 77 * Set the default size for printable characters: 78 * From <Space> to '~' is 1 (printable), others are 2 (not printable). 79 * This also inits all 'isident' and 'isfname' flags to FALSE. 80 * 81 * EBCDIC: all chars below ' ' are not printable, all others are 82 * printable. 83 */ 84 c = 0; 85 while (c < ' ') 86 chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2; 87 #ifdef EBCDIC 88 while (c < 255) 89 #else 90 while (c <= '~') 91 #endif 92 chartab[c++] = 1 + CT_PRINT_CHAR; 93 #ifdef FEAT_FKMAP 94 if (p_altkeymap) 95 { 96 while (c < YE) 97 chartab[c++] = 1 + CT_PRINT_CHAR; 98 } 99 #endif 100 while (c < 256) 101 { 102 #ifdef FEAT_MBYTE 103 /* UTF-8: bytes 0xa0 - 0xff are printable (latin1) */ 104 if (enc_utf8 && c >= 0xa0) 105 chartab[c++] = CT_PRINT_CHAR + 1; 106 /* euc-jp characters starting with 0x8e are single width */ 107 else if (enc_dbcs == DBCS_JPNU && c == 0x8e) 108 chartab[c++] = CT_PRINT_CHAR + 1; 109 /* other double-byte chars can be printable AND double-width */ 110 else if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2) 111 chartab[c++] = CT_PRINT_CHAR + 2; 112 else 113 #endif 114 /* the rest is unprintable by default */ 115 chartab[c++] = (dy_flags & DY_UHEX) ? 4 : 2; 116 } 117 118 #ifdef FEAT_MBYTE 119 /* Assume that every multi-byte char is a filename character. */ 120 for (c = 1; c < 256; ++c) 121 if ((enc_dbcs != 0 && MB_BYTE2LEN(c) > 1) 122 || (enc_dbcs == DBCS_JPNU && c == 0x8e) 123 || (enc_utf8 && c >= 0xa0)) 124 chartab[c] |= CT_FNAME_CHAR; 125 #endif 126 } 127 128 /* 129 * Init word char flags all to FALSE 130 */ 131 vim_memset(buf->b_chartab, 0, (size_t)32); 132 #ifdef FEAT_MBYTE 133 for (c = 0; c < 256; ++c) 134 { 135 /* double-byte characters are probably word characters */ 136 if (enc_dbcs != 0 && MB_BYTE2LEN(c) == 2) 137 SET_CHARTAB(buf, c); 138 } 139 #endif 140 141 #ifdef FEAT_LISP 142 /* 143 * In lisp mode the '-' character is included in keywords. 144 */ 145 if (buf->b_p_lisp) 146 SET_CHARTAB(buf, '-'); 147 #endif 148 149 /* Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint' 150 * options Each option is a list of characters, character numbers or 151 * ranges, separated by commas, e.g.: "200-210,x,#-178,-" 152 */ 153 for (i = global ? 0 : 3; i <= 3; ++i) 154 { 155 if (i == 0) 156 p = p_isi; /* first round: 'isident' */ 157 else if (i == 1) 158 p = p_isp; /* second round: 'isprint' */ 159 else if (i == 2) 160 p = p_isf; /* third round: 'isfname' */ 161 else /* i == 3 */ 162 p = buf->b_p_isk; /* fourth round: 'iskeyword' */ 163 164 while (*p) 165 { 166 tilde = FALSE; 167 do_isalpha = FALSE; 168 if (*p == '^' && p[1] != NUL) 169 { 170 tilde = TRUE; 171 ++p; 172 } 173 if (VIM_ISDIGIT(*p)) 174 c = getdigits(&p); 175 else 176 c = *p++; 177 c2 = -1; 178 if (*p == '-' && p[1] != NUL) 179 { 180 ++p; 181 if (VIM_ISDIGIT(*p)) 182 c2 = getdigits(&p); 183 else 184 c2 = *p++; 185 } 186 if (c <= 0 || (c2 < c && c2 != -1) || c2 >= 256 187 || !(*p == NUL || *p == ',')) 188 return FAIL; 189 190 if (c2 == -1) /* not a range */ 191 { 192 /* 193 * A single '@' (not "@-@"): 194 * Decide on letters being ID/printable/keyword chars with 195 * standard function isalpha(). This takes care of locale for 196 * single-byte characters). 197 */ 198 if (c == '@') 199 { 200 do_isalpha = TRUE; 201 c = 1; 202 c2 = 255; 203 } 204 else 205 c2 = c; 206 } 207 while (c <= c2) 208 { 209 if (!do_isalpha || isalpha(c) 210 #ifdef FEAT_FKMAP 211 || (p_altkeymap && (F_isalpha(c) || F_isdigit(c))) 212 #endif 213 ) 214 { 215 if (i == 0) /* (re)set ID flag */ 216 { 217 if (tilde) 218 chartab[c] &= ~CT_ID_CHAR; 219 else 220 chartab[c] |= CT_ID_CHAR; 221 } 222 else if (i == 1) /* (re)set printable */ 223 { 224 if ((c < ' ' 225 #ifndef EBCDIC 226 || c > '~' 227 #endif 228 #ifdef FEAT_FKMAP 229 || (p_altkeymap 230 && (F_isalpha(c) || F_isdigit(c))) 231 #endif 232 ) 233 #ifdef FEAT_MBYTE 234 /* For double-byte we keep the cell width, so 235 * that we can detect it from the first byte. */ 236 && !(enc_dbcs && MB_BYTE2LEN(c) == 2) 237 #endif 238 ) 239 { 240 if (tilde) 241 { 242 chartab[c] = (chartab[c] & ~CT_CELL_MASK) 243 + ((dy_flags & DY_UHEX) ? 4 : 2); 244 chartab[c] &= ~CT_PRINT_CHAR; 245 } 246 else 247 { 248 chartab[c] = (chartab[c] & ~CT_CELL_MASK) + 1; 249 chartab[c] |= CT_PRINT_CHAR; 250 } 251 } 252 } 253 else if (i == 2) /* (re)set fname flag */ 254 { 255 if (tilde) 256 chartab[c] &= ~CT_FNAME_CHAR; 257 else 258 chartab[c] |= CT_FNAME_CHAR; 259 } 260 else /* i == 3 */ /* (re)set keyword flag */ 261 { 262 if (tilde) 263 RESET_CHARTAB(buf, c); 264 else 265 SET_CHARTAB(buf, c); 266 } 267 } 268 ++c; 269 } 270 p = skip_to_option_part(p); 271 } 272 } 273 chartab_initialized = TRUE; 274 return OK; 275 } 276 277 /* 278 * Translate any special characters in buf[bufsize] in-place. 279 * The result is a string with only printable characters, but if there is not 280 * enough room, not all characters will be translated. 281 */ 282 void 283 trans_characters(buf, bufsize) 284 char_u *buf; 285 int bufsize; 286 { 287 int len; /* length of string needing translation */ 288 int room; /* room in buffer after string */ 289 char_u *trs; /* translated character */ 290 int trs_len; /* length of trs[] */ 291 292 len = (int)STRLEN(buf); 293 room = bufsize - len; 294 while (*buf != 0) 295 { 296 # ifdef FEAT_MBYTE 297 /* Assume a multi-byte character doesn't need translation. */ 298 if (has_mbyte && (trs_len = (*mb_ptr2len_check)(buf)) > 1) 299 len -= trs_len; 300 else 301 # endif 302 { 303 trs = transchar_byte(*buf); 304 trs_len = (int)STRLEN(trs); 305 if (trs_len > 1) 306 { 307 room -= trs_len - 1; 308 if (room <= 0) 309 return; 310 mch_memmove(buf + trs_len, buf + 1, (size_t)len); 311 } 312 mch_memmove(buf, trs, (size_t)trs_len); 313 --len; 314 } 315 buf += trs_len; 316 } 317 } 318 319 #if defined(FEAT_EVAL) || defined(FEAT_TITLE) || defined(PROTO) 320 /* 321 * Translate a string into allocated memory, replacing special chars with 322 * printable chars. Returns NULL when out of memory. 323 */ 324 char_u * 325 transstr(s) 326 char_u *s; 327 { 328 char_u *res; 329 char_u *p; 330 #ifdef FEAT_MBYTE 331 int l, len, c; 332 char_u hexbuf[11]; 333 #endif 334 335 #ifdef FEAT_MBYTE 336 if (has_mbyte) 337 { 338 /* Compute the length of the result, taking account of unprintable 339 * multi-byte characters. */ 340 len = 0; 341 p = s; 342 while (*p != NUL) 343 { 344 if ((l = (*mb_ptr2len_check)(p)) > 1) 345 { 346 c = (*mb_ptr2char)(p); 347 p += l; 348 if (vim_isprintc(c)) 349 len += l; 350 else 351 { 352 transchar_hex(hexbuf, c); 353 len += STRLEN(hexbuf); 354 } 355 } 356 else 357 { 358 l = byte2cells(*p++); 359 if (l > 0) 360 len += l; 361 else 362 len += 4; /* illegal byte sequence */ 363 } 364 } 365 res = alloc((unsigned)(len + 1)); 366 } 367 else 368 #endif 369 res = alloc((unsigned)(vim_strsize(s) + 1)); 370 if (res != NULL) 371 { 372 *res = NUL; 373 p = s; 374 while (*p != NUL) 375 { 376 #ifdef FEAT_MBYTE 377 if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1) 378 { 379 c = (*mb_ptr2char)(p); 380 if (vim_isprintc(c)) 381 STRNCAT(res, p, l); /* append printable multi-byte char */ 382 else 383 transchar_hex(res + STRLEN(res), c); 384 p += l; 385 } 386 else 387 #endif 388 STRCAT(res, transchar_byte(*p++)); 389 } 390 } 391 return res; 392 } 393 #endif 394 395 #if defined(FEAT_SYN_HL) || defined(FEAT_INS_EXPAND) || defined(PROTO) 396 /* 397 * Convert the string "p[len]" to do ignore-case comparing. Uses the current 398 * locale. Returns an allocated string (NULL for out-of-memory). 399 */ 400 char_u * 401 str_foldcase(str, len) 402 char_u *str; 403 int len; 404 { 405 garray_T ga; 406 int i; 407 408 #define GA_CHAR(i) ((char_u *)ga.ga_data)[i] 409 #define GA_PTR(i) ((char_u *)ga.ga_data + i) 410 411 /* Copy "str" into allocated memory, unmodified. */ 412 ga_init2(&ga, 1, 10); 413 if (ga_grow(&ga, len + 1) == FAIL) 414 return NULL; 415 mch_memmove(ga.ga_data, str, (size_t)len); 416 GA_CHAR(len) = NUL; 417 ga.ga_len = len; 418 ga.ga_room -= len; 419 420 /* Make each character lower case. */ 421 i = 0; 422 while (GA_CHAR(i) != NUL) 423 { 424 #ifdef FEAT_MBYTE 425 if (enc_utf8 || (has_mbyte && MB_BYTE2LEN(GA_CHAR(i)) > 1)) 426 { 427 if (enc_utf8) 428 { 429 int c, lc; 430 431 c = utf_ptr2char(GA_PTR(i)); 432 lc = utf_tolower(c); 433 if (c != lc) 434 { 435 int ol = utf_char2len(c); 436 int nl = utf_char2len(lc); 437 438 /* If the byte length changes need to shift the following 439 * characters forward or backward. */ 440 if (ol != nl) 441 { 442 if (nl > ol) 443 if (ga_grow(&ga, nl - ol) == FAIL) 444 { 445 /* out of memory, keep old char */ 446 lc = c; 447 nl = ol; 448 } 449 if (ol != nl) 450 { 451 mch_memmove(GA_PTR(i) + nl, GA_PTR(i) + ol, 452 STRLEN(GA_PTR(i) + ol) + 1); 453 ga.ga_len += nl - ol; 454 ga.ga_room -= nl - ol; 455 } 456 } 457 (void)utf_char2bytes(lc, GA_PTR(i)); 458 } 459 } 460 /* skip to next multi-byte char */ 461 i += (*mb_ptr2len_check)(GA_PTR(i)); 462 } 463 else 464 #endif 465 { 466 GA_CHAR(i) = TOLOWER_LOC(GA_CHAR(i)); 467 ++i; 468 } 469 } 470 471 return (char_u *)ga.ga_data; 472 } 473 #endif 474 475 /* 476 * Catch 22: chartab[] can't be initialized before the options are 477 * initialized, and initializing options may cause transchar() to be called! 478 * When chartab_initialized == FALSE don't use chartab[]. 479 * Does NOT work for multi-byte characters, c must be <= 255. 480 * Also doesn't work for the first byte of a multi-byte, "c" must be a 481 * character! 482 */ 483 static char_u transchar_buf[7]; 484 485 char_u * 486 transchar(c) 487 int c; 488 { 489 int i; 490 491 i = 0; 492 if (IS_SPECIAL(c)) /* special key code, display as ~@ char */ 493 { 494 transchar_buf[0] = '~'; 495 transchar_buf[1] = '@'; 496 i = 2; 497 c = K_SECOND(c); 498 } 499 500 if ((!chartab_initialized && ( 501 #ifdef EBCDIC 502 (c >= 64 && c < 255) 503 #else 504 (c >= ' ' && c <= '~') 505 #endif 506 #ifdef FEAT_FKMAP 507 || F_ischar(c) 508 #endif 509 )) || (c < 256 && vim_isprintc_strict(c))) 510 { 511 /* printable character */ 512 transchar_buf[i] = c; 513 transchar_buf[i + 1] = NUL; 514 } 515 else 516 transchar_nonprint(transchar_buf + i, c); 517 return transchar_buf; 518 } 519 520 #if defined(FEAT_MBYTE) || defined(PROTO) 521 /* 522 * Like transchar(), but called with a byte instead of a character. Checks 523 * for an illegal UTF-8 byte. 524 */ 525 char_u * 526 transchar_byte(c) 527 int c; 528 { 529 if (enc_utf8 && c >= 0x80) 530 { 531 transchar_nonprint(transchar_buf, c); 532 return transchar_buf; 533 } 534 return transchar(c); 535 } 536 #endif 537 538 /* 539 * Convert non-printable character to two or more printable characters in 540 * "buf[]". "buf" needs to be able to hold five bytes. 541 * Does NOT work for multi-byte characters, c must be <= 255. 542 */ 543 void 544 transchar_nonprint(buf, c) 545 char_u *buf; 546 int c; 547 { 548 if (c == NL) 549 c = NUL; /* we use newline in place of a NUL */ 550 else if (c == CAR && get_fileformat(curbuf) == EOL_MAC) 551 c = NL; /* we use CR in place of NL in this case */ 552 553 if (dy_flags & DY_UHEX) /* 'display' has "uhex" */ 554 transchar_hex(buf, c); 555 556 #ifdef EBCDIC 557 /* For EBCDIC only the characters 0-63 and 255 are not printable */ 558 else if (CtrlChar(c) != 0 || c == DEL) 559 #else 560 else if (c <= 0x7f) /* 0x00 - 0x1f and 0x7f */ 561 #endif 562 { 563 buf[0] = '^'; 564 #ifdef EBCDIC 565 if (c == DEL) 566 buf[1] = '?'; /* DEL displayed as ^? */ 567 else 568 buf[1] = CtrlChar(c); 569 #else 570 buf[1] = c ^ 0x40; /* DEL displayed as ^? */ 571 #endif 572 573 buf[2] = NUL; 574 } 575 #ifdef FEAT_MBYTE 576 else if (enc_utf8 && c >= 0x80) 577 { 578 transchar_hex(buf, c); 579 } 580 #endif 581 #ifndef EBCDIC 582 else if (c >= ' ' + 0x80 && c <= '~' + 0x80) /* 0xa0 - 0xfe */ 583 { 584 buf[0] = '|'; 585 buf[1] = c - 0x80; 586 buf[2] = NUL; 587 } 588 #else 589 else if (c < 64) 590 { 591 buf[0] = '~'; 592 buf[1] = MetaChar(c); 593 buf[2] = NUL; 594 } 595 #endif 596 else /* 0x80 - 0x9f and 0xff */ 597 { 598 /* 599 * TODO: EBCDIC I don't know what to do with this chars, so I display 600 * them as '~?' for now 601 */ 602 buf[0] = '~'; 603 #ifdef EBCDIC 604 buf[1] = '?'; /* 0xff displayed as ~? */ 605 #else 606 buf[1] = (c - 0x80) ^ 0x40; /* 0xff displayed as ~? */ 607 #endif 608 buf[2] = NUL; 609 } 610 } 611 612 void 613 transchar_hex(buf, c) 614 char_u *buf; 615 int c; 616 { 617 int i = 0; 618 619 buf[0] = '<'; 620 #ifdef FEAT_MBYTE 621 if (c > 255) 622 { 623 buf[++i] = nr2hex((unsigned)c >> 12); 624 buf[++i] = nr2hex((unsigned)c >> 8); 625 } 626 #endif 627 buf[++i] = nr2hex((unsigned)c >> 4); 628 buf[++i] = nr2hex(c); 629 buf[++i] = '>'; 630 buf[++i] = NUL; 631 } 632 633 /* 634 * Convert the lower 4 bits of byte "c" to its hex character. 635 * Lower case letters are used to avoid the confusion of <F1> being 0xf1 or 636 * function key 1. 637 */ 638 static int 639 nr2hex(c) 640 int c; 641 { 642 if ((c & 0xf) <= 9) 643 return (c & 0xf) + '0'; 644 return (c & 0xf) - 10 + 'a'; 645 } 646 647 /* 648 * Return number of display cells occupied by byte "b". 649 * Caller must make sure 0 <= b <= 255. 650 * For multi-byte mode "b" must be the first byte of a character. 651 * A TAB is counted as two cells: "^I". 652 * For UTF-8 mode this will return 0 for bytes >= 0x80, because the number of 653 * cells depends on further bytes. 654 */ 655 int 656 byte2cells(b) 657 int b; 658 { 659 #ifdef FEAT_MBYTE 660 if (enc_utf8 && b >= 0x80) 661 return 0; 662 #endif 663 return (chartab[b] & CT_CELL_MASK); 664 } 665 666 /* 667 * Return number of display cells occupied by character "c". 668 * "c" can be a special key (negative number) in which case 3 or 4 is returned. 669 * A TAB is counted as two cells: "^I" or four: "<09>". 670 */ 671 int 672 char2cells(c) 673 int c; 674 { 675 if (IS_SPECIAL(c)) 676 return char2cells(K_SECOND(c)) + 2; 677 #ifdef FEAT_MBYTE 678 if (c >= 0x80) 679 { 680 /* UTF-8: above 0x80 need to check the value */ 681 if (enc_utf8) 682 return utf_char2cells(c); 683 /* DBCS: double-byte means double-width, except for euc-jp with first 684 * byte 0x8e */ 685 if (enc_dbcs != 0 && c >= 0x100) 686 { 687 if (enc_dbcs == DBCS_JPNU && ((unsigned)c >> 8) == 0x8e) 688 return 1; 689 return 2; 690 } 691 } 692 #endif 693 return (chartab[c & 0xff] & CT_CELL_MASK); 694 } 695 696 /* 697 * Return number of display cells occupied by character at "*p". 698 * A TAB is counted as two cells: "^I" or four: "<09>". 699 */ 700 int 701 ptr2cells(p) 702 char_u *p; 703 { 704 #ifdef FEAT_MBYTE 705 /* For UTF-8 we need to look at more bytes if the first byte is >= 0x80. */ 706 if (enc_utf8 && *p >= 0x80) 707 return utf_ptr2cells(p); 708 /* For DBCS we can tell the cell count from the first byte. */ 709 #endif 710 return (chartab[*p] & CT_CELL_MASK); 711 } 712 713 /* 714 * Return the number of characters string "s" will take on the screen, 715 * counting TABs as two characters: "^I". 716 */ 717 int 718 vim_strsize(s) 719 char_u *s; 720 { 721 return vim_strnsize(s, (int)MAXCOL); 722 } 723 724 /* 725 * Return the number of characters string "s[len]" will take on the screen, 726 * counting TABs as two characters: "^I". 727 */ 728 int 729 vim_strnsize(s, len) 730 char_u *s; 731 int len; 732 { 733 int size = 0; 734 735 while (*s != NUL && --len >= 0) 736 { 737 #ifdef FEAT_MBYTE 738 if (has_mbyte) 739 { 740 int l = (*mb_ptr2len_check)(s); 741 742 size += ptr2cells(s); 743 s += l; 744 len -= l - 1; 745 } 746 else 747 #endif 748 size += byte2cells(*s++); 749 } 750 return size; 751 } 752 753 /* 754 * Return the number of characters 'c' will take on the screen, taking 755 * into account the size of a tab. 756 * Use a define to make it fast, this is used very often!!! 757 * Also see getvcol() below. 758 */ 759 760 #define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \ 761 if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \ 762 { \ 763 int ts; \ 764 ts = (buf)->b_p_ts; \ 765 return (int)(ts - (col % ts)); \ 766 } \ 767 else \ 768 return ptr2cells(p); 769 770 #if defined(FEAT_VREPLACE) || defined(FEAT_EX_EXTRA) || defined(FEAT_GUI) \ 771 || defined(FEAT_VIRTUALEDIT) || defined(PROTO) 772 int 773 chartabsize(p, col) 774 char_u *p; 775 colnr_T col; 776 { 777 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, p, col) 778 } 779 #endif 780 781 #ifdef FEAT_LINEBREAK 782 static int 783 win_chartabsize(wp, p, col) 784 win_T *wp; 785 char_u *p; 786 colnr_T col; 787 { 788 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, p, col) 789 } 790 #endif 791 792 /* 793 * return the number of characters the string 's' will take on the screen, 794 * taking into account the size of a tab 795 */ 796 int 797 linetabsize(s) 798 char_u *s; 799 { 800 colnr_T col = 0; 801 802 while (*s != NUL) 803 col += lbr_chartabsize_adv(&s, col); 804 return (int)col; 805 } 806 807 /* 808 * Like linetabsize(), but for a given window instead of the current one. 809 */ 810 int 811 win_linetabsize(wp, p, len) 812 win_T *wp; 813 char_u *p; 814 colnr_T len; 815 { 816 colnr_T col = 0; 817 char_u *s; 818 819 for (s = p; *s != NUL && (len == MAXCOL || s < p + len); ) 820 { 821 col += win_lbr_chartabsize(wp, s, col, NULL); 822 #ifdef FEAT_MBYTE 823 if (has_mbyte) 824 s += (*mb_ptr2len_check)(s); 825 else 826 #endif 827 ++s; 828 } 829 return (int)col; 830 } 831 832 /* 833 * return TRUE if 'c' is a normal identifier character 834 * letters and characters from 'isident' option. 835 */ 836 int 837 vim_isIDc(c) 838 int c; 839 { 840 return (c > 0 && c < 0x100 && (chartab[c] & CT_ID_CHAR)); 841 } 842 843 /* 844 * return TRUE if 'c' is a keyword character: Letters and characters from 845 * 'iskeyword' option for current buffer. 846 * For multi-byte characters mb_get_class() is used (builtin rules). 847 */ 848 int 849 vim_iswordc(c) 850 int c; 851 { 852 #ifdef FEAT_MBYTE 853 if (c >= 0x100) 854 { 855 if (enc_dbcs != 0) 856 return dbcs_class((unsigned)c >> 8, c & 0xff) >= 2; 857 if (enc_utf8) 858 return utf_class(c) >= 2; 859 } 860 #endif 861 return (c > 0 && c < 0x100 && GET_CHARTAB(curbuf, c) != 0); 862 } 863 864 /* 865 * Just like vim_iswordc() but uses a pointer to the (multi-byte) character. 866 */ 867 int 868 vim_iswordp(p) 869 char_u *p; 870 { 871 #ifdef FEAT_MBYTE 872 if (has_mbyte && MB_BYTE2LEN(*p) > 1) 873 return mb_get_class(p) >= 2; 874 #endif 875 return GET_CHARTAB(curbuf, *p) != 0; 876 } 877 878 #if defined(FEAT_SYN_HL) || defined(PROTO) 879 int 880 vim_iswordc_buf(p, buf) 881 char_u *p; 882 buf_T *buf; 883 { 884 # ifdef FEAT_MBYTE 885 if (has_mbyte && MB_BYTE2LEN(*p) > 1) 886 return mb_get_class(p) >= 2; 887 # endif 888 return (GET_CHARTAB(buf, *p) != 0); 889 } 890 #endif 891 892 /* 893 * return TRUE if 'c' is a valid file-name character 894 * Assume characters above 0x100 are valid (multi-byte). 895 */ 896 int 897 vim_isfilec(c) 898 int c; 899 { 900 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_FNAME_CHAR))); 901 } 902 903 /* 904 * return TRUE if 'c' is a printable character 905 * Assume characters above 0x100 are printable (multi-byte), except for 906 * Unicode. 907 */ 908 int 909 vim_isprintc(c) 910 int c; 911 { 912 #ifdef FEAT_MBYTE 913 if (enc_utf8 && c >= 0x100) 914 return utf_printable(c); 915 #endif 916 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR))); 917 } 918 919 /* 920 * Strict version of vim_isprintc(c), don't return TRUE if "c" is the head 921 * byte of a double-byte character. 922 */ 923 int 924 vim_isprintc_strict(c) 925 int c; 926 { 927 #ifdef FEAT_MBYTE 928 if (enc_dbcs != 0 && c < 0x100 && MB_BYTE2LEN(c) > 1) 929 return FALSE; 930 if (enc_utf8 && c >= 0x100) 931 return utf_printable(c); 932 #endif 933 return (c >= 0x100 || (c > 0 && (chartab[c] & CT_PRINT_CHAR))); 934 } 935 936 /* 937 * like chartabsize(), but also check for line breaks on the screen 938 */ 939 int 940 lbr_chartabsize(s, col) 941 unsigned char *s; 942 colnr_T col; 943 { 944 #ifdef FEAT_LINEBREAK 945 if (!curwin->w_p_lbr && *p_sbr == NUL) 946 { 947 #endif 948 #ifdef FEAT_MBYTE 949 if (curwin->w_p_wrap) 950 return win_nolbr_chartabsize(curwin, s, col, NULL); 951 #endif 952 RET_WIN_BUF_CHARTABSIZE(curwin, curbuf, s, col) 953 #ifdef FEAT_LINEBREAK 954 } 955 return win_lbr_chartabsize(curwin, s, col, NULL); 956 #endif 957 } 958 959 /* 960 * Call lbr_chartabsize() and advance the pointer. 961 */ 962 int 963 lbr_chartabsize_adv(s, col) 964 char_u **s; 965 colnr_T col; 966 { 967 int retval; 968 969 retval = lbr_chartabsize(*s, col); 970 #ifdef FEAT_MBYTE 971 if (has_mbyte) 972 *s += (*mb_ptr2len_check)(*s); 973 else 974 #endif 975 ++*s; 976 return retval; 977 } 978 979 /* 980 * This function is used very often, keep it fast!!!! 981 * 982 * If "headp" not NULL, set *headp to the size of what we for 'showbreak' 983 * string at start of line. Warning: *headp is only set if it's a non-zero 984 * value, init to 0 before calling. 985 */ 986 /*ARGSUSED*/ 987 int 988 win_lbr_chartabsize(wp, s, col, headp) 989 win_T *wp; 990 char_u *s; 991 colnr_T col; 992 int *headp; 993 { 994 #ifdef FEAT_LINEBREAK 995 int c; 996 int size; 997 colnr_T col2; 998 colnr_T colmax; 999 int added; 1000 # ifdef FEAT_MBYTE 1001 int mb_added = 0; 1002 # else 1003 # define mb_added 0 1004 # endif 1005 int numberextra; 1006 char_u *ps; 1007 int tab_corr = (*s == TAB); 1008 1009 /* 1010 * No 'linebreak' and 'showbreak': return quickly. 1011 */ 1012 if (!wp->w_p_lbr && *p_sbr == NUL) 1013 #endif 1014 { 1015 #ifdef FEAT_MBYTE 1016 if (wp->w_p_wrap) 1017 return win_nolbr_chartabsize(wp, s, col, headp); 1018 #endif 1019 RET_WIN_BUF_CHARTABSIZE(wp, wp->w_buffer, s, col) 1020 } 1021 1022 #ifdef FEAT_LINEBREAK 1023 /* 1024 * First get normal size, without 'linebreak' 1025 */ 1026 size = win_chartabsize(wp, s, col); 1027 c = *s; 1028 1029 /* 1030 * If 'linebreak' set check at a blank before a non-blank if the line 1031 * needs a break here 1032 */ 1033 if (wp->w_p_lbr 1034 && vim_isbreak(c) 1035 && !vim_isbreak(s[1]) 1036 && !wp->w_p_list 1037 && wp->w_p_wrap 1038 # ifdef FEAT_VERTSPLIT 1039 && wp->w_width != 0 1040 # endif 1041 ) 1042 { 1043 /* 1044 * Count all characters from first non-blank after a blank up to next 1045 * non-blank after a blank. 1046 */ 1047 numberextra = win_col_off(wp); 1048 col2 = col; 1049 colmax = W_WIDTH(wp) - numberextra; 1050 if (col >= colmax) 1051 colmax += (((col - colmax) 1052 / (colmax + win_col_off2(wp))) + 1) 1053 * (colmax + win_col_off2(wp)); 1054 for (;;) 1055 { 1056 ps = s; 1057 # ifdef FEAT_MBYTE 1058 if (has_mbyte) 1059 s += (*mb_ptr2len_check)(s); 1060 else 1061 # endif 1062 ++s; 1063 c = *s; 1064 if (!(c != NUL 1065 && (vim_isbreak(c) 1066 || (!vim_isbreak(c) 1067 && (col2 == col || !vim_isbreak(*ps)))))) 1068 break; 1069 1070 col2 += win_chartabsize(wp, s, col2); 1071 if (col2 >= colmax) /* doesn't fit */ 1072 { 1073 size = colmax - col; 1074 tab_corr = FALSE; 1075 break; 1076 } 1077 } 1078 } 1079 # ifdef FEAT_MBYTE 1080 else if (has_mbyte && size == 2 && MB_BYTE2LEN(*s) > 1 1081 && wp->w_p_wrap && in_win_border(wp, col)) 1082 { 1083 ++size; /* Count the ">" in the last column. */ 1084 mb_added = 1; 1085 } 1086 # endif 1087 1088 /* 1089 * May have to add something for 'showbreak' string at start of line 1090 * Set *headp to the size of what we add. 1091 */ 1092 added = 0; 1093 if (*p_sbr != NUL && wp->w_p_wrap && col != 0) 1094 { 1095 numberextra = win_col_off(wp); 1096 col += numberextra + mb_added; 1097 if (col >= (colnr_T)W_WIDTH(wp)) 1098 { 1099 col -= W_WIDTH(wp); 1100 numberextra = W_WIDTH(wp) - (numberextra - win_col_off2(wp)); 1101 if (numberextra > 0) 1102 col = col % numberextra; 1103 } 1104 if (col == 0 || col + size > (colnr_T)W_WIDTH(wp)) 1105 { 1106 added = vim_strsize(p_sbr); 1107 if (tab_corr) 1108 size += (added / wp->w_buffer->b_p_ts) * wp->w_buffer->b_p_ts; 1109 else 1110 size += added; 1111 if (col != 0) 1112 added = 0; 1113 } 1114 } 1115 if (headp != NULL) 1116 *headp = added + mb_added; 1117 return size; 1118 #endif 1119 } 1120 1121 #if defined(FEAT_MBYTE) || defined(PROTO) 1122 /* 1123 * Like win_lbr_chartabsize(), except that we know 'linebreak' is off and 1124 * 'wrap' is on. This means we need to check for a double-byte character that 1125 * doesn't fit at the end of the screen line. 1126 */ 1127 static int 1128 win_nolbr_chartabsize(wp, s, col, headp) 1129 win_T *wp; 1130 char_u *s; 1131 colnr_T col; 1132 int *headp; 1133 { 1134 int n; 1135 1136 if (*s == TAB && (!wp->w_p_list || lcs_tab1)) 1137 { 1138 n = wp->w_buffer->b_p_ts; 1139 return (int)(n - (col % n)); 1140 } 1141 n = ptr2cells(s); 1142 /* Add one cell for a double-width character in the last column of the 1143 * window, displayed with a ">". */ 1144 if (n == 2 && MB_BYTE2LEN(*s) > 1 && in_win_border(wp, col)) 1145 { 1146 if (headp != NULL) 1147 *headp = 1; 1148 return 3; 1149 } 1150 return n; 1151 } 1152 1153 /* 1154 * Return TRUE if virtual column "vcol" is in the rightmost column of window 1155 * "wp". 1156 */ 1157 int 1158 in_win_border(wp, vcol) 1159 win_T *wp; 1160 colnr_T vcol; 1161 { 1162 colnr_T width1; /* width of first line (after line number) */ 1163 colnr_T width2; /* width of further lines */ 1164 1165 #ifdef FEAT_VERTSPLIT 1166 if (wp->w_width == 0) /* there is no border */ 1167 return FALSE; 1168 #endif 1169 width1 = W_WIDTH(wp) - win_col_off(wp); 1170 if (vcol < width1 - 1) 1171 return FALSE; 1172 if (vcol == width1 - 1) 1173 return TRUE; 1174 width2 = width1 + win_col_off2(wp); 1175 return ((vcol - width1) % width2 == width2 - 1); 1176 } 1177 #endif /* FEAT_MBYTE */ 1178 1179 /* 1180 * Get virtual column number of pos. 1181 * start: on the first position of this character (TAB, ctrl) 1182 * cursor: where the cursor is on this character (first char, except for TAB) 1183 * end: on the last position of this character (TAB, ctrl) 1184 * 1185 * This is used very often, keep it fast! 1186 */ 1187 void 1188 getvcol(wp, pos, start, cursor, end) 1189 win_T *wp; 1190 pos_T *pos; 1191 colnr_T *start; 1192 colnr_T *cursor; 1193 colnr_T *end; 1194 { 1195 colnr_T vcol; 1196 char_u *ptr; /* points to current char */ 1197 char_u *posptr; /* points to char at pos->col */ 1198 int incr; 1199 int head; 1200 int ts = wp->w_buffer->b_p_ts; 1201 int c; 1202 1203 vcol = 0; 1204 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE); 1205 posptr = ptr + pos->col; 1206 1207 /* 1208 * This function is used very often, do some speed optimizations. 1209 * When 'list', 'linebreak' and 'showbreak' are not set use a simple loop. 1210 * Also use this when 'list' is set but tabs take their normal size. 1211 */ 1212 if ((!wp->w_p_list || lcs_tab1 != NUL) 1213 #ifdef FEAT_LINEBREAK 1214 && !wp->w_p_lbr && *p_sbr == NUL 1215 #endif 1216 ) 1217 { 1218 #ifndef FEAT_MBYTE 1219 head = 0; 1220 #endif 1221 for (;;) 1222 { 1223 #ifdef FEAT_MBYTE 1224 head = 0; 1225 #endif 1226 c = *ptr; 1227 /* make sure we don't go past the end of the line */ 1228 if (c == NUL) 1229 { 1230 incr = 1; /* NUL at end of line only takes one column */ 1231 break; 1232 } 1233 /* A tab gets expanded, depending on the current column */ 1234 if (c == TAB) 1235 incr = ts - (vcol % ts); 1236 else 1237 { 1238 #ifdef FEAT_MBYTE 1239 if (has_mbyte) 1240 { 1241 /* For utf-8, if the byte is >= 0x80, need to look at 1242 * further bytes to find the cell width. */ 1243 if (enc_utf8 && c >= 0x80) 1244 incr = utf_ptr2cells(ptr); 1245 else 1246 incr = CHARSIZE(c); 1247 1248 /* If a double-cell char doesn't fit at the end of a line 1249 * it wraps to the next line, it's like this char is three 1250 * cells wide. */ 1251 if (incr == 2 && wp->w_p_wrap && in_win_border(wp, vcol)) 1252 { 1253 ++incr; 1254 head = 1; 1255 } 1256 } 1257 else 1258 #endif 1259 incr = CHARSIZE(c); 1260 } 1261 1262 if (ptr >= posptr) /* character at pos->col */ 1263 break; 1264 1265 vcol += incr; 1266 #ifdef FEAT_MBYTE 1267 if (has_mbyte) 1268 ptr += (*mb_ptr2len_check)(ptr); 1269 else 1270 #endif 1271 ++ptr; 1272 } 1273 } 1274 else 1275 { 1276 for (;;) 1277 { 1278 /* A tab gets expanded, depending on the current column */ 1279 head = 0; 1280 incr = win_lbr_chartabsize(wp, ptr, vcol, &head); 1281 /* make sure we don't go past the end of the line */ 1282 if (*ptr == NUL) 1283 { 1284 incr = 1; /* NUL at end of line only takes one column */ 1285 break; 1286 } 1287 1288 if (ptr >= posptr) /* character at pos->col */ 1289 break; 1290 1291 vcol += incr; 1292 #ifdef FEAT_MBYTE 1293 if (has_mbyte) 1294 ptr += (*mb_ptr2len_check)(ptr); 1295 else 1296 #endif 1297 ++ptr; 1298 } 1299 } 1300 if (start != NULL) 1301 *start = vcol + head; 1302 if (end != NULL) 1303 *end = vcol + incr - 1; 1304 if (cursor != NULL) 1305 { 1306 if (*ptr == TAB 1307 && (State & NORMAL) 1308 && !wp->w_p_list 1309 && !virtual_active() 1310 #ifdef FEAT_VISUAL 1311 && !(VIsual_active 1312 && (*p_sel == 'e' || ltoreq(*pos, VIsual))) 1313 #endif 1314 ) 1315 *cursor = vcol + incr - 1; /* cursor at end */ 1316 else 1317 *cursor = vcol + head; /* cursor at start */ 1318 } 1319 } 1320 1321 /* 1322 * Get virtual cursor column in the current window, pretending 'list' is off. 1323 */ 1324 colnr_T 1325 getvcol_nolist(posp) 1326 pos_T *posp; 1327 { 1328 int list_save = curwin->w_p_list; 1329 colnr_T vcol; 1330 1331 curwin->w_p_list = FALSE; 1332 getvcol(curwin, posp, NULL, &vcol, NULL); 1333 curwin->w_p_list = list_save; 1334 return vcol; 1335 } 1336 1337 #if defined(FEAT_VIRTUALEDIT) || defined(PROTO) 1338 /* 1339 * Get virtual column in virtual mode. 1340 */ 1341 void 1342 getvvcol(wp, pos, start, cursor, end) 1343 win_T *wp; 1344 pos_T *pos; 1345 colnr_T *start; 1346 colnr_T *cursor; 1347 colnr_T *end; 1348 { 1349 colnr_T col; 1350 colnr_T coladd; 1351 colnr_T endadd; 1352 # ifdef FEAT_MBYTE 1353 char_u *ptr; 1354 # endif 1355 1356 if (virtual_active()) 1357 { 1358 /* For virtual mode, only want one value */ 1359 getvcol(wp, pos, &col, NULL, NULL); 1360 1361 coladd = pos->coladd; 1362 endadd = 0; 1363 # ifdef FEAT_MBYTE 1364 /* Cannot put the cursor on part of a wide character. */ 1365 ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE); 1366 if (pos->col < STRLEN(ptr)) 1367 { 1368 int c = (*mb_ptr2char)(ptr + pos->col); 1369 1370 if (c != TAB && vim_isprintc(c)) 1371 { 1372 endadd = char2cells(c) - 1; 1373 if (coladd >= endadd) 1374 coladd -= endadd; 1375 else 1376 coladd = 0; 1377 } 1378 } 1379 # endif 1380 col += coladd; 1381 if (start != NULL) 1382 *start = col; 1383 if (cursor != NULL) 1384 *cursor = col; 1385 if (end != NULL) 1386 *end = col + endadd; 1387 } 1388 else 1389 getvcol(wp, pos, start, cursor, end); 1390 } 1391 #endif 1392 1393 #if defined(FEAT_VISUAL) || defined(PROTO) 1394 /* 1395 * Get the leftmost and rightmost virtual column of pos1 and pos2. 1396 * Used for Visual block mode. 1397 */ 1398 void 1399 getvcols(wp, pos1, pos2, left, right) 1400 win_T *wp; 1401 pos_T *pos1, *pos2; 1402 colnr_T *left, *right; 1403 { 1404 colnr_T from1, from2, to1, to2; 1405 1406 if (ltp(pos1, pos2)) 1407 { 1408 getvvcol(wp, pos1, &from1, NULL, &to1); 1409 getvvcol(wp, pos2, &from2, NULL, &to2); 1410 } 1411 else 1412 { 1413 getvvcol(wp, pos2, &from1, NULL, &to1); 1414 getvvcol(wp, pos1, &from2, NULL, &to2); 1415 } 1416 if (from2 < from1) 1417 *left = from2; 1418 else 1419 *left = from1; 1420 if (to2 > to1) 1421 { 1422 if (*p_sel == 'e' && from2 - 1 >= to1) 1423 *right = from2 - 1; 1424 else 1425 *right = to2; 1426 } 1427 else 1428 *right = to1; 1429 } 1430 #endif 1431 1432 /* 1433 * skipwhite: skip over ' ' and '\t'. 1434 */ 1435 char_u * 1436 skipwhite(p) 1437 char_u *p; 1438 { 1439 while (vim_iswhite(*p)) /* skip to next non-white */ 1440 ++p; 1441 return p; 1442 } 1443 1444 /* 1445 * skipdigits: skip over digits; 1446 */ 1447 char_u * 1448 skipdigits(p) 1449 char_u *p; 1450 { 1451 while (VIM_ISDIGIT(*p)) /* skip to next non-digit */ 1452 ++p; 1453 return p; 1454 } 1455 1456 /* 1457 * Variant of isdigit() that can handle characters > 0x100. 1458 * We don't use isdigit() here, because on some systems it also considers 1459 * superscript 1 to be a digit. 1460 * Use the VIM_ISDIGIT() macro for simple arguments. 1461 */ 1462 int 1463 vim_isdigit(c) 1464 int c; 1465 { 1466 return (c >= '0' && c <= '9'); 1467 } 1468 1469 /* 1470 * Variant of isxdigit() that can handle characters > 0x100. 1471 * We don't use isxdigit() here, because on some systems it also considers 1472 * superscript 1 to be a digit. 1473 */ 1474 int 1475 vim_isxdigit(c) 1476 int c; 1477 { 1478 return (c >= '0' && c <= '9') 1479 || (c >= 'a' && c <= 'f') 1480 || (c >= 'A' && c <= 'F'); 1481 } 1482 1483 /* 1484 * skiptowhite: skip over text until ' ' or '\t' or NUL. 1485 */ 1486 char_u * 1487 skiptowhite(p) 1488 char_u *p; 1489 { 1490 while (*p != ' ' && *p != '\t' && *p != NUL) 1491 ++p; 1492 return p; 1493 } 1494 1495 #if defined(FEAT_LISTCMDS) || defined(FEAT_SIGNS) || defined(FEAT_SNIFF) \ 1496 || defined(PROTO) 1497 /* 1498 * skiptowhite_esc: Like skiptowhite(), but also skip escaped chars 1499 */ 1500 char_u * 1501 skiptowhite_esc(p) 1502 char_u *p; 1503 { 1504 while (*p != ' ' && *p != '\t' && *p != NUL) 1505 { 1506 if ((*p == '\\' || *p == Ctrl_V) && *(p + 1) != NUL) 1507 ++p; 1508 ++p; 1509 } 1510 return p; 1511 } 1512 #endif 1513 1514 /* 1515 * Getdigits: Get a number from a string and skip over it. 1516 * Note: the argument is a pointer to a char_u pointer! 1517 */ 1518 long 1519 getdigits(pp) 1520 char_u **pp; 1521 { 1522 char_u *p; 1523 long retval; 1524 1525 p = *pp; 1526 retval = atol((char *)p); 1527 if (*p == '-') /* skip negative sign */ 1528 ++p; 1529 p = skipdigits(p); /* skip to next non-digit */ 1530 *pp = p; 1531 return retval; 1532 } 1533 1534 /* 1535 * Return TRUE if "lbuf" is empty or only contains blanks. 1536 */ 1537 int 1538 vim_isblankline(lbuf) 1539 char_u *lbuf; 1540 { 1541 char_u *p; 1542 1543 p = skipwhite(lbuf); 1544 return (*p == NUL || *p == '\r' || *p == '\n'); 1545 } 1546 1547 /* 1548 * Convert a string into a long and/or unsigned long, taking care of 1549 * hexadecimal and octal numbers. Accepts a '-' sign. 1550 * If "hexp" is not NULL, returns a flag to indicate the type of the number: 1551 * 0 decimal 1552 * '0' octal 1553 * 'X' hex 1554 * 'x' hex 1555 * If "len" is not NULL, the length of the number in characters is returned. 1556 * If "nptr" is not NULL, the signed result is returned in it. 1557 * If "unptr" is not NULL, the unsigned result is returned in it. 1558 */ 1559 void 1560 vim_str2nr(start, hexp, len, dooct, dohex, nptr, unptr) 1561 char_u *start; 1562 int *hexp; /* return: type of number 0 = decimal, 'x' 1563 or 'X' is hex, '0' = octal */ 1564 int *len; /* return: detected length of number */ 1565 int dooct; /* recognize octal number */ 1566 int dohex; /* recognize hex number */ 1567 long *nptr; /* return: signed result */ 1568 unsigned long *unptr; /* return: unsigned result */ 1569 { 1570 char_u *ptr = start; 1571 int hex = 0; /* default is decimal */ 1572 int negative = FALSE; 1573 unsigned long un = 0; 1574 1575 if (ptr[0] == '-') 1576 { 1577 negative = TRUE; 1578 ++ptr; 1579 } 1580 1581 if (ptr[0] == '0') /* could be hex or octal */ 1582 { 1583 hex = ptr[1]; 1584 if (dohex && (hex == 'X' || hex == 'x') && vim_isxdigit(ptr[2])) 1585 ptr += 2; /* hexadecimal */ 1586 else 1587 { 1588 if (dooct && VIM_ISDIGIT(hex)) 1589 hex = '0'; /* octal */ 1590 else 1591 hex = 0; /* 0 by itself is decimal */ 1592 } 1593 } 1594 1595 /* 1596 * Do the string-to-numeric conversion "manually" to avoid sscanf quirks. 1597 */ 1598 if (hex) 1599 { 1600 if (hex == '0') 1601 { 1602 /* octal */ 1603 while ('0' <= *ptr && *ptr <= '7') 1604 { 1605 un = 8 * un + (unsigned long)(*ptr - '0'); 1606 ++ptr; 1607 } 1608 } 1609 else 1610 { 1611 /* hex */ 1612 while (vim_isxdigit(*ptr)) 1613 { 1614 un = 16 * un + (unsigned long)hex2nr(*ptr); 1615 ++ptr; 1616 } 1617 } 1618 } 1619 else 1620 { 1621 /* decimal */ 1622 while (VIM_ISDIGIT(*ptr)) 1623 { 1624 un = 10 * un + (unsigned long)(*ptr - '0'); 1625 ++ptr; 1626 } 1627 } 1628 1629 if (hexp != NULL) 1630 *hexp = hex; 1631 if (len != NULL) 1632 *len = (int)(ptr - start); 1633 if (nptr != NULL) 1634 { 1635 if (negative) /* account for leading '-' for decimal numbers */ 1636 *nptr = -(long)un; 1637 else 1638 *nptr = (long)un; 1639 } 1640 if (unptr != NULL) 1641 *unptr = un; 1642 } 1643 1644 /* 1645 * Return the value of a single hex character. 1646 * Only valid when the argument is '0' - '9', 'A' - 'F' or 'a' - 'f'. 1647 */ 1648 int 1649 hex2nr(c) 1650 int c; 1651 { 1652 if (c >= 'a' && c <= 'f') 1653 return c - 'a' + 10; 1654 if (c >= 'A' && c <= 'F') 1655 return c - 'A' + 10; 1656 return c - '0'; 1657 } 1658 1659 #if defined(FEAT_TERMRESPONSE) \ 1660 || (defined(FEAT_GUI_GTK) && defined(FEAT_WINDOWS)) || defined(PROTO) 1661 /* 1662 * Convert two hex characters to a byte. 1663 * Return -1 if one of the characters is not hex. 1664 */ 1665 int 1666 hexhex2nr(p) 1667 char_u *p; 1668 { 1669 if (!vim_isxdigit(p[0]) || !vim_isxdigit(p[1])) 1670 return -1; 1671 return (hex2nr(p[0]) << 4) + hex2nr(p[1]); 1672 } 1673 #endif 1674 1675 /* 1676 * Return TRUE if "str" starts with a backslash that should be removed. 1677 * For MS-DOS, WIN32 and OS/2 this is only done when the character after the 1678 * backslash is not a normal file name character. 1679 * '$' is a valid file name character, we don't remove the backslash before 1680 * it. This means it is not possible to use an environment variable after a 1681 * backslash. "C:\$VIM\doc" is taken literally, only "$VIM\doc" works. 1682 * Although "\ name" is valid, the backslash in "Program\ files" must be 1683 * removed. Assume a file name doesn't start with a space. 1684 * For multi-byte names, never remove a backslash before a non-ascii 1685 * character, assume that all multi-byte characters are valid file name 1686 * characters. 1687 */ 1688 int 1689 rem_backslash(str) 1690 char_u *str; 1691 { 1692 #ifdef BACKSLASH_IN_FILENAME 1693 return (str[0] == '\\' 1694 # ifdef FEAT_MBYTE 1695 && str[1] < 0x80 1696 # endif 1697 && (str[1] == ' ' 1698 || (str[1] != NUL 1699 && str[1] != '*' 1700 && str[1] != '?' 1701 && !vim_isfilec(str[1])))); 1702 #else 1703 return (str[0] == '\\' && str[1] != NUL); 1704 #endif 1705 } 1706 1707 /* 1708 * Halve the number of backslashes in a file name argument. 1709 * For MS-DOS we only do this if the character after the backslash 1710 * is not a normal file character. 1711 */ 1712 void 1713 backslash_halve(p) 1714 char_u *p; 1715 { 1716 for ( ; *p; ++p) 1717 if (rem_backslash(p)) 1718 STRCPY(p, p + 1); 1719 } 1720 1721 /* 1722 * backslash_halve() plus save the result in allocated memory. 1723 */ 1724 char_u * 1725 backslash_halve_save(p) 1726 char_u *p; 1727 { 1728 char_u *res; 1729 1730 res = vim_strsave(p); 1731 if (res == NULL) 1732 return p; 1733 backslash_halve(res); 1734 return res; 1735 } 1736 1737 #if (defined(EBCDIC) && defined(FEAT_POSTSCRIPT)) || defined(PROTO) 1738 /* 1739 * Table for EBCDIC to ASCII conversion unashamedly taken from xxd.c! 1740 * The first 64 entries have been added to map control characters defined in 1741 * ascii.h 1742 */ 1743 static char_u ebcdic2ascii_tab[256] = 1744 { 1745 0000, 0001, 0002, 0003, 0004, 0011, 0006, 0177, 1746 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017, 1747 0020, 0021, 0022, 0023, 0024, 0012, 0010, 0027, 1748 0030, 0031, 0032, 0033, 0033, 0035, 0036, 0037, 1749 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047, 1750 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057, 1751 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, 1752 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077, 1753 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246, 1754 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174, 1755 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257, 1756 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176, 1757 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267, 1758 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077, 1759 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301, 1760 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042, 1761 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147, 1762 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311, 1763 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160, 1764 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320, 1765 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170, 1766 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327, 1767 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337, 1768 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347, 1769 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107, 1770 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355, 1771 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120, 1772 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363, 1773 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130, 1774 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371, 1775 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067, 1776 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377 1777 }; 1778 1779 /* 1780 * Convert a buffer worth of characters from EBCDIC to ASCII. Only useful if 1781 * wanting 7-bit ASCII characters out the other end. 1782 */ 1783 void 1784 ebcdic2ascii(buffer, len) 1785 char_u *buffer; 1786 int len; 1787 { 1788 int i; 1789 1790 for (i = 0; i < len; i++) 1791 buffer[i] = ebcdic2ascii_tab[buffer[i]]; 1792 } 1793 #endif 1794