home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / src / charset.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-05-24  |  38.6 KB  |  1,766 lines

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