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 / patches / 6.2.511 < prev    next >
Encoding:
Internet Message Format  |  2004-04-27  |  23.0 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 6.2.511
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=ISO-8859-1
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 6.2.511
  11. Problem:    Tags in Russian help files are in utf-8 encoding, which may be
  12.         different from 'encoding'.
  13. Solution:   Use the "TAG_FILE_ENCODING" field in the tags file to specify the
  14.         encoding of the tags.  Convert help tags from 'encoding' to the
  15.         tag file encoding when searching for matches, do the reverse when
  16.         listing help tags.
  17. Files:        runtime/doc/tagsrch.txt, src/ex_cmds.c, src/tag.c
  18.  
  19.  
  20. *** ../vim-6.2.510/runtime/doc/tagsrch.txt    Sun Jun  1 12:20:35 2003
  21. --- runtime/doc/tagsrch.txt    Wed Apr 28 11:58:29 2004
  22. ***************
  23. *** 1,4 ****
  24. ! *tagsrch.txt*   For Vim version 6.2.  Last change: 2003 May 18
  25.   
  26.   
  27.             VIM REFERENCE MANUAL    by Bram Moolenaar
  28. --- 1,4 ----
  29. ! *tagsrch.txt*   For Vim version 6.2.  Last change: 2004 Apr 28
  30.   
  31.   
  32.             VIM REFERENCE MANUAL    by Bram Moolenaar
  33. ***************
  34. *** 546,565 ****
  35.   The first lines in the tags file can contain lines that start with
  36.       !_TAG_
  37.   These are sorted to the first lines, only rare tags that start with "!" can
  38. ! sort to before them.  Vim only recognizes the line that indicates if the file
  39. ! was sorted.  When this line is found, Vim uses binary searching for the tags
  40. ! file: >
  41. !     !_TAG_FILE_SORTED<Tab>1
  42. ! <
  43.   A tag file may be case-fold sorted to avoid a linear search when 'ignorecase'
  44. ! is on.  See 'tagbsearch' for details.  The value '2' should be used then: >
  45. !     !_TAG_FILE_SORTED<Tab>2
  46. ! <
  47.                               *tag-search*
  48.   The command can be any Ex command, but often it is a search command.
  49. ! Examples: >
  50. !     tag1    file1    /^main(argc, argv)/
  51. !     tag2    file2    108
  52.   
  53.   The command is always executed with 'magic' not set.  The only special
  54.   characters in a search pattern are "^" (begin-of-line) and "$" (<EOL>).
  55. --- 548,575 ----
  56.   The first lines in the tags file can contain lines that start with
  57.       !_TAG_
  58.   These are sorted to the first lines, only rare tags that start with "!" can
  59. ! sort to before them.  Vim recognizes two items.  The first one is the line
  60. ! that indicates if the file was sorted.  When this line is found, Vim uses
  61. ! binary searching for the tags file:
  62. !     !_TAG_FILE_SORTED<Tab>1 ~
  63.   A tag file may be case-fold sorted to avoid a linear search when 'ignorecase'
  64. ! is on.  See 'tagbsearch' for details.  The value '2' should be used then:
  65. !     !_TAG_FILE_SORTED<Tab>2 ~
  66. ! The other tag that Vim recognizes, but only when compiled with the
  67. ! |+multi_byte| feature, is the encoding of the tags file:
  68. !     !_TAG_FILE_ENCODING<Tab>utf-8 ~
  69. ! Here "utf-8" is the encoding used for the tags.  Vim will then convert the tag
  70. ! being searched for from 'encoding' to the encoding of the tags file.  And when
  71. ! listing tags the reverse happens.  When the conversion fails the unconverted
  72. ! tag is used.
  73.                               *tag-search*
  74.   The command can be any Ex command, but often it is a search command.
  75. ! Examples:
  76. !     tag1    file1    /^main(argc, argv)/ ~
  77. !     tag2    file2    108 ~
  78.   
  79.   The command is always executed with 'magic' not set.  The only special
  80.   characters in a search pattern are "^" (begin-of-line) and "$" (<EOL>).
  81. *** ../vim-6.2.510/src/ex_cmds.c    Mon Apr 19 20:26:42 2004
  82. --- src/ex_cmds.c    Wed Apr 28 15:02:02 2004
  83. ***************
  84. *** 5275,5280 ****
  85. --- 5275,5285 ----
  86.       char_u    *s;
  87.       int        i;
  88.       char_u    *fname;
  89. + # ifdef FEAT_MBYTE
  90. +     int        utf8 = MAYBE;
  91. +     int        this_utf8;
  92. +     int        firstline;
  93. + # endif
  94.   
  95.       /*
  96.        * Find all *.txt files.
  97. ***************
  98. *** 5342,5349 ****
  99. --- 5347,5375 ----
  100.       }
  101.       fname = gettail(files[fi]);
  102.   
  103. + # ifdef FEAT_MBYTE
  104. +     firstline = TRUE;
  105. + # endif
  106.       while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int)
  107.       {
  108. + # ifdef FEAT_MBYTE
  109. +         if (firstline)
  110. +         {
  111. +         /* Detect utf-8 file by a non-ASCII char in the first line. */
  112. +         this_utf8 = FALSE;
  113. +         for (s = IObuff; *s != NUL; ++s)
  114. +             if (*s >= 0x80)
  115. +             this_utf8 = TRUE;
  116. +         if (utf8 == MAYBE)
  117. +             utf8 = this_utf8;
  118. +         else if (utf8 != this_utf8)
  119. +         {
  120. +             EMSG2(_("E670: Mix of help file encodings within a language: %s"), files[fi]);
  121. +             got_int = TRUE;
  122. +         }
  123. +         firstline = FALSE;
  124. +         }
  125. + # endif
  126.           p1 = vim_strchr(IObuff, '*');    /* find first '*' */
  127.           while (p1 != NULL)
  128.           {
  129. ***************
  130. *** 5426,5431 ****
  131. --- 5452,5462 ----
  132.           ++p2;
  133.           }
  134.       }
  135. + # ifdef FEAT_MBYTE
  136. +     if (utf8 == TRUE)
  137. +         fprintf(fd_tags, "!_TAG_FILE_ENCODING\tutf-8\t//\n");
  138. + # endif
  139.   
  140.       /*
  141.        * Write the tags into the file.
  142. *** ../vim-6.2.510/src/tag.c    Mon Apr 19 20:26:43 2004
  143. --- src/tag.c    Wed Apr 28 14:39:14 2004
  144. ***************
  145. *** 1005,1010 ****
  146. --- 1005,1060 ----
  147.   #endif
  148.   
  149.   /*
  150. +  * Structure to hold info about the tag pattern being used.
  151. +  */
  152. + typedef struct
  153. + {
  154. +     char_u    *pat;        /* the pattern */
  155. +     int        len;        /* length of pat[] */
  156. +     char_u    *head;        /* start of pattern head */
  157. +     int        headlen;    /* length of head[] */
  158. +     regmatch_T    regmatch;    /* regexp program, may be NULL */
  159. + } pat_T;
  160. + static void prepare_pats __ARGS((pat_T *pats, int has_re));
  161. + /*
  162. +  * Extract info from the tag search pattern "pats->pat".
  163. +  */
  164. +     static void
  165. + prepare_pats(pats, has_re)
  166. +     pat_T    *pats;
  167. +     int        has_re;
  168. + {
  169. +     pats->head = pats->pat;
  170. +     pats->headlen = pats->len;
  171. +     if (has_re)
  172. +     {
  173. +     /* When the pattern starts with '^' or "\\<", binary searching can be
  174. +      * used (much faster). */
  175. +     if (pats->pat[0] == '^')
  176. +         pats->head = pats->pat + 1;
  177. +     else if (pats->pat[0] == '\\' && pats->pat[1] == '<')
  178. +         pats->head = pats->pat + 2;
  179. +     if (pats->head == pats->pat)
  180. +         pats->headlen = 0;
  181. +     else
  182. +         for (pats->headlen = 0; pats->head[pats->headlen] != NUL;
  183. +                                   ++pats->headlen)
  184. +         if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"),
  185. +                        pats->head[pats->headlen]) != NULL)
  186. +             break;
  187. +     if (p_tl != 0 && pats->headlen > p_tl)    /* adjust for 'taglength' */
  188. +         pats->headlen = p_tl;
  189. +     }
  190. +     if (has_re)
  191. +     pats->regmatch.regprog = vim_regcomp(pats->pat, p_magic ? RE_MAGIC : 0);
  192. +     else
  193. +     pats->regmatch.regprog = NULL;
  194. + }
  195. + /*
  196.    * find_tags() - search for tags in tags files
  197.    *
  198.    * Return FAIL if search completely failed (*num_matches will be 0, *matchesp
  199. ***************
  200. *** 1053,1059 ****
  201.       char_u    *p;
  202.       char_u    *s;
  203.       int        i;
  204. -     regmatch_T    regmatch;        /* regexp program may be NULL */
  205.   #ifdef FEAT_TAG_BINS
  206.       struct tag_search_info    /* Binary search file offsets */
  207.       {
  208. --- 1103,1108 ----
  209. ***************
  210. *** 1124,1132 ****
  211.       char_u    *saved_pat = NULL;        /* copy of pat[] */
  212.   #endif
  213.   
  214. !     int        patlen;                /* length of pat[] */
  215. !     char_u    *pathead;            /* start of pattern head */
  216. !     int        patheadlen;            /* length of pathead[] */
  217.   #ifdef FEAT_TAG_BINS
  218.       int        findall = (mincount == MAXCOL || mincount == TAG_MANY);
  219.                           /* find all matching tags */
  220. --- 1173,1188 ----
  221.       char_u    *saved_pat = NULL;        /* copy of pat[] */
  222.   #endif
  223.   
  224. !     /* Use two sets of variables for the pattern: "orgpat" holds the values
  225. !      * for the original pattern and "convpat" converted from 'encoding' to
  226. !      * encoding of the tags file.  "pats" point to either one of these. */
  227. !     pat_T    *pats;
  228. !     pat_T    orgpat;            /* holds unconverted pattern info */
  229. ! #ifdef FEAT_MBYTE
  230. !     pat_T    convpat;        /* holds converted pattern info */
  231. !     vimconv_T    vimconv;
  232. ! #endif
  233.   #ifdef FEAT_TAG_BINS
  234.       int        findall = (mincount == MAXCOL || mincount == TAG_MANY);
  235.                           /* find all matching tags */
  236. ***************
  237. *** 1146,1151 ****
  238. --- 1202,1212 ----
  239.       int        verbose = (flags & TAG_VERBOSE);
  240.   
  241.       help_save = curbuf->b_help;
  242. +     orgpat.pat = pat;
  243. +     pats = &orgpat;
  244. + #ifdef FEAT_MBYTE
  245. +     vimconv.vc_type = CONV_NONE;
  246. + #endif
  247.   
  248.   /*
  249.    * Allocate memory for the buffers that are used
  250. ***************
  251. *** 1176,1230 ****
  252.       if (help_only)                /* want tags from help file */
  253.       curbuf->b_help = TRUE;            /* will be restored later */
  254.   
  255. !     patlen = (int)STRLEN(pat);
  256.   #ifdef FEAT_MULTI_LANG
  257.       if (curbuf->b_help)
  258.       {
  259.       /* When "@ab" is specified use only the "ab" language, otherwise
  260.        * search all languages. */
  261. !     if (patlen > 3 && pat[patlen - 3] == '@'
  262. !                          && ASCII_ISALPHA(pat[patlen - 2])
  263. !                         && ASCII_ISALPHA(pat[patlen - 1]))
  264.       {
  265. !         saved_pat = vim_strnsave(pat, patlen - 3);
  266.           if (saved_pat != NULL)
  267.           {
  268. !         help_lang_find = &pat[patlen - 2];
  269. !         pat = saved_pat;
  270. !         patlen -= 3;
  271.           }
  272.       }
  273.       }
  274.   #endif
  275.   
  276. !     if (p_tl != 0 && patlen > p_tl)        /* adjust for 'taglength' */
  277. !     patlen = p_tl;
  278. !     pathead = pat;
  279. !     patheadlen = patlen;
  280. !     if (has_re)
  281. !     {
  282. !     /* When the pattern starts with '^' or "\\<", binary searching can be
  283. !      * used (much faster). */
  284. !     if (pat[0] == '^')
  285. !         pathead = pat + 1;
  286. !     else if (pat[0] == '\\' && pat[1] == '<')
  287. !         pathead = pat + 2;
  288. !     if (pathead == pat)
  289. !         patheadlen = 0;
  290. !     else
  291. !         for (patheadlen = 0; pathead[patheadlen] != NUL; ++patheadlen)
  292. !         if (vim_strchr((char_u *)(p_magic ? ".[~*\\$" : "\\$"),
  293. !                          pathead[patheadlen]) != NULL)
  294. !             break;
  295. !     if (p_tl != 0 && patheadlen > p_tl)    /* adjust for 'taglength' */
  296. !         patheadlen = p_tl;
  297. !     }
  298. !     if (has_re)
  299. !     regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0);
  300. !     else
  301. !     regmatch.regprog = NULL;
  302.   
  303.   #ifdef FEAT_TAG_BINS
  304.       /* This is only to avoid a compiler warning for using search_info
  305. --- 1237,1266 ----
  306.       if (help_only)                /* want tags from help file */
  307.       curbuf->b_help = TRUE;            /* will be restored later */
  308.   
  309. !     pats->len = (int)STRLEN(pat);
  310.   #ifdef FEAT_MULTI_LANG
  311.       if (curbuf->b_help)
  312.       {
  313.       /* When "@ab" is specified use only the "ab" language, otherwise
  314.        * search all languages. */
  315. !     if (pats->len > 3 && pat[pats->len - 3] == '@'
  316. !                       && ASCII_ISALPHA(pat[pats->len - 2])
  317. !                      && ASCII_ISALPHA(pat[pats->len - 1]))
  318.       {
  319. !         saved_pat = vim_strnsave(pat, pats->len - 3);
  320.           if (saved_pat != NULL)
  321.           {
  322. !         help_lang_find = &pat[pats->len - 2];
  323. !         pats->pat = saved_pat;
  324. !         pats->len -= 3;
  325.           }
  326.       }
  327.       }
  328.   #endif
  329. +     if (p_tl != 0 && pats->len > p_tl)        /* adjust for 'taglength' */
  330. +     pats->len = p_tl;
  331.   
  332. !     prepare_pats(pats, has_re);
  333.   
  334.   #ifdef FEAT_TAG_BINS
  335.       /* This is only to avoid a compiler warning for using search_info
  336. ***************
  337. *** 1242,1254 ****
  338.    * Only ignore case when TAG_NOIC not used or 'ignorecase' set.
  339.    */
  340.   #ifdef FEAT_TAG_BINS
  341. !     regmatch.rm_ic = ((p_ic || !noic)
  342. !                    && (findall || patheadlen == 0 || !p_tbs));
  343.       for (round = 1; round <= 2; ++round)
  344.       {
  345. !       linear = (patheadlen == 0 || !p_tbs || round == 2);
  346.   #else
  347. !       regmatch.rm_ic = (p_ic || !noic);
  348.   #endif
  349.   
  350.         /*
  351. --- 1278,1290 ----
  352.    * Only ignore case when TAG_NOIC not used or 'ignorecase' set.
  353.    */
  354.   #ifdef FEAT_TAG_BINS
  355. !     pats->regmatch.rm_ic = ((p_ic || !noic)
  356. !                    && (findall || pats->headlen == 0 || !p_tbs));
  357.       for (round = 1; round <= 2; ++round)
  358.       {
  359. !       linear = (pats->headlen == 0 || !p_tbs || round == 2);
  360.   #else
  361. !       pats->regmatch.rm_ic = (p_ic || !noic);
  362.   #endif
  363.   
  364.         /*
  365. ***************
  366. *** 1566,1578 ****
  367.               {
  368.               state = TS_BINARY;
  369.               sortic = TRUE;
  370. !             regmatch.rm_ic = (p_ic || !noic);
  371.               }
  372.               else
  373.               state = TS_LINEAR;
  374.           }
  375.   
  376. !         if (state == TS_BINARY && regmatch.rm_ic && !sortic)
  377.           {
  378.               /* binary search won't work for ignoring case, use linear
  379.                * search. */
  380. --- 1602,1614 ----
  381.               {
  382.               state = TS_BINARY;
  383.               sortic = TRUE;
  384. !             pats->regmatch.rm_ic = (p_ic || !noic);
  385.               }
  386.               else
  387.               state = TS_LINEAR;
  388.           }
  389.   
  390. !         if (state == TS_BINARY && pats->regmatch.rm_ic && !sortic)
  391.           {
  392.               /* binary search won't work for ignoring case, use linear
  393.                * search. */
  394. ***************
  395. *** 1612,1623 ****
  396.   #endif
  397.           }
  398.   
  399.           /*
  400.            * Figure out where the different strings are in this line.
  401.            * For "normal" tags: Do a quick check if the tag matches.
  402.            * This speeds up tag searching a lot!
  403.            */
  404. !         if (patheadlen
  405.   #ifdef FEAT_EMACS_TAGS
  406.                   && !is_etag
  407.   #endif
  408. --- 1648,1687 ----
  409.   #endif
  410.           }
  411.   
  412. + #ifdef FEAT_MBYTE
  413. +         if (lbuf[0] == '!' && pats == &orgpat
  414. +                && STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0)
  415. +         {
  416. +         /* Convert the search pattern from 'encoding' to the
  417. +          * specified encoding. */
  418. +         for (p = lbuf + 20; *p > ' ' && *p < 127; ++p)
  419. +             ;
  420. +         *p = NUL;
  421. +         convert_setup(&vimconv, p_enc, lbuf + 20);
  422. +         if (vimconv.vc_type != CONV_NONE)
  423. +         {
  424. +             convpat.pat = string_convert(&vimconv, pats->pat, NULL);
  425. +             if (convpat.pat != NULL)
  426. +             {
  427. +             pats = &convpat;
  428. +             pats->len = (int)STRLEN(pats->pat);
  429. +             prepare_pats(pats, has_re);
  430. +             pats->regmatch.rm_ic = orgpat.regmatch.rm_ic;
  431. +             }
  432. +         }
  433. +         /* Prepare for converting a match the other way around. */
  434. +         convert_setup(&vimconv, lbuf + 20, p_enc);
  435. +         continue;
  436. +         }
  437. + #endif
  438.           /*
  439.            * Figure out where the different strings are in this line.
  440.            * For "normal" tags: Do a quick check if the tag matches.
  441.            * This speeds up tag searching a lot!
  442.            */
  443. !         if (pats->headlen
  444.   #ifdef FEAT_EMACS_TAGS
  445.                   && !is_etag
  446.   #endif
  447. ***************
  448. *** 1674,1682 ****
  449.           cmplen = (int)(tagp.tagname_end - tagp.tagname);
  450.           if (p_tl != 0 && cmplen > p_tl)        /* adjust for 'taglength' */
  451.               cmplen = p_tl;
  452. !         if (has_re && patheadlen < cmplen)
  453. !             cmplen = patheadlen;
  454. !         else if (state == TS_LINEAR && patheadlen != cmplen)
  455.               continue;
  456.   
  457.   #ifdef FEAT_TAG_BINS
  458. --- 1738,1746 ----
  459.           cmplen = (int)(tagp.tagname_end - tagp.tagname);
  460.           if (p_tl != 0 && cmplen > p_tl)        /* adjust for 'taglength' */
  461.               cmplen = p_tl;
  462. !         if (has_re && pats->headlen < cmplen)
  463. !             cmplen = pats->headlen;
  464. !         else if (state == TS_LINEAR && pats->headlen != cmplen)
  465.               continue;
  466.   
  467.   #ifdef FEAT_TAG_BINS
  468. ***************
  469. *** 1695,1704 ****
  470.                * Compare the current tag with the searched tag.
  471.                */
  472.               if (sortic)
  473. !             tagcmp = tag_strnicmp(tagp.tagname, pathead,
  474.                                     (size_t)cmplen);
  475.               else
  476. !             tagcmp = STRNCMP(tagp.tagname, pathead, cmplen);
  477.   
  478.               /*
  479.                * A match with a shorter tag means to search forward.
  480. --- 1759,1768 ----
  481.                * Compare the current tag with the searched tag.
  482.                */
  483.               if (sortic)
  484. !             tagcmp = tag_strnicmp(tagp.tagname, pats->head,
  485.                                     (size_t)cmplen);
  486.               else
  487. !             tagcmp = STRNCMP(tagp.tagname, pats->head, cmplen);
  488.   
  489.               /*
  490.                * A match with a shorter tag means to search forward.
  491. ***************
  492. *** 1706,1714 ****
  493.                */
  494.               if (tagcmp == 0)
  495.               {
  496. !             if (cmplen < patheadlen)
  497.                   tagcmp = -1;
  498. !             else if (cmplen > patheadlen)
  499.                   tagcmp = 1;
  500.               }
  501.   
  502. --- 1770,1778 ----
  503.                */
  504.               if (tagcmp == 0)
  505.               {
  506. !             if (cmplen < pats->headlen)
  507.                   tagcmp = -1;
  508. !             else if (cmplen > pats->headlen)
  509.                   tagcmp = 1;
  510.               }
  511.   
  512. ***************
  513. *** 1752,1758 ****
  514.           }
  515.           else if (state == TS_SKIP_BACK)
  516.           {
  517. !             if (MB_STRNICMP(tagp.tagname, pathead, cmplen) != 0)
  518.               state = TS_STEP_FORWARD;
  519.               else
  520.               /* Have to skip back more.  Restore the curr_offset
  521. --- 1816,1822 ----
  522.           }
  523.           else if (state == TS_SKIP_BACK)
  524.           {
  525. !             if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0)
  526.               state = TS_STEP_FORWARD;
  527.               else
  528.               /* Have to skip back more.  Restore the curr_offset
  529. ***************
  530. *** 1762,1768 ****
  531.           }
  532.           else if (state == TS_STEP_FORWARD)
  533.           {
  534. !             if (MB_STRNICMP(tagp.tagname, pathead, cmplen) != 0)
  535.               {
  536.               if ((off_t)ftell(fp) > search_info.match_offset)
  537.                   break;    /* past last match */
  538. --- 1826,1832 ----
  539.           }
  540.           else if (state == TS_STEP_FORWARD)
  541.           {
  542. !             if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0)
  543.               {
  544.               if ((off_t)ftell(fp) > search_info.match_offset)
  545.                   break;    /* past last match */
  546. ***************
  547. *** 1773,1779 ****
  548.           else
  549.   #endif
  550.               /* skip this match if it can't match */
  551. !             if (MB_STRNICMP(tagp.tagname, pathead, cmplen) != 0)
  552.               continue;
  553.   
  554.           /*
  555. --- 1837,1843 ----
  556.           else
  557.   #endif
  558.               /* skip this match if it can't match */
  559. !             if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0)
  560.               continue;
  561.   
  562.           /*
  563. ***************
  564. *** 1824,1863 ****
  565.           if (p_tl != 0 && cmplen > p_tl)        /* adjust for 'taglength' */
  566.           cmplen = p_tl;
  567.           /* if tag length does not match, don't try comparing */
  568. !         if (patlen != cmplen)
  569.           match = FALSE;
  570.           else
  571.           {
  572. !         if (regmatch.rm_ic)
  573.           {
  574. !             match = (MB_STRNICMP(tagp.tagname, pat, cmplen) == 0);
  575.               if (match)
  576. !             match_no_ic = (STRNCMP(tagp.tagname, pat, cmplen) == 0);
  577.           }
  578.           else
  579. !             match = (STRNCMP(tagp.tagname, pat, cmplen) == 0);
  580.           }
  581.   
  582.           /*
  583.            * Has a regexp: Also find tags matching regexp.
  584.            */
  585.           match_re = FALSE;
  586. !         if (!match && regmatch.regprog != NULL)
  587.           {
  588.           int    cc;
  589.   
  590.           cc = *tagp.tagname_end;
  591.           *tagp.tagname_end = NUL;
  592. !         match = vim_regexec(®match, tagp.tagname, (colnr_T)0);
  593.           if (match)
  594.           {
  595. !             matchoff = (int)(regmatch.startp[0] - tagp.tagname);
  596. !             if (regmatch.rm_ic)
  597.               {
  598. !             regmatch.rm_ic = FALSE;
  599. !             match_no_ic = vim_regexec(®match, tagp.tagname,
  600.                                     (colnr_T)0);
  601. !             regmatch.rm_ic = TRUE;
  602.               }
  603.           }
  604.           *tagp.tagname_end = cc;
  605. --- 1888,1928 ----
  606.           if (p_tl != 0 && cmplen > p_tl)        /* adjust for 'taglength' */
  607.           cmplen = p_tl;
  608.           /* if tag length does not match, don't try comparing */
  609. !         if (pats->len != cmplen)
  610.           match = FALSE;
  611.           else
  612.           {
  613. !         if (pats->regmatch.rm_ic)
  614.           {
  615. !             match = (MB_STRNICMP(tagp.tagname, pats->pat, cmplen) == 0);
  616.               if (match)
  617. !             match_no_ic = (STRNCMP(tagp.tagname, pats->pat,
  618. !                                 cmplen) == 0);
  619.           }
  620.           else
  621. !             match = (STRNCMP(tagp.tagname, pats->pat, cmplen) == 0);
  622.           }
  623.   
  624.           /*
  625.            * Has a regexp: Also find tags matching regexp.
  626.            */
  627.           match_re = FALSE;
  628. !         if (!match && pats->regmatch.regprog != NULL)
  629.           {
  630.           int    cc;
  631.   
  632.           cc = *tagp.tagname_end;
  633.           *tagp.tagname_end = NUL;
  634. !         match = vim_regexec(&pats->regmatch, tagp.tagname, (colnr_T)0);
  635.           if (match)
  636.           {
  637. !             matchoff = (int)(pats->regmatch.startp[0] - tagp.tagname);
  638. !             if (pats->regmatch.rm_ic)
  639.               {
  640. !             pats->regmatch.rm_ic = FALSE;
  641. !             match_no_ic = vim_regexec(&pats->regmatch, tagp.tagname,
  642.                                     (colnr_T)0);
  643. !             pats->regmatch.rm_ic = TRUE;
  644.               }
  645.           }
  646.           *tagp.tagname_end = cc;
  647. ***************
  648. *** 1914,1920 ****
  649.               else
  650.                   mtt = MT_GL_OTH;
  651.               }
  652. !             if (regmatch.rm_ic && !match_no_ic)
  653.               mtt += MT_IC_OFF;
  654.               if (match_re)
  655.               mtt += MT_RE_OFF;
  656. --- 1979,1985 ----
  657.               else
  658.                   mtt = MT_GL_OTH;
  659.               }
  660. !             if (pats->regmatch.rm_ic && !match_no_ic)
  661.               mtt += MT_IC_OFF;
  662.               if (match_re)
  663.               mtt += MT_RE_OFF;
  664. ***************
  665. *** 1927,1932 ****
  666. --- 1992,2026 ----
  667.            */
  668.           if (ga_grow(&ga_match[mtt], 1) == OK)
  669.           {
  670. + #ifdef FEAT_MBYTE
  671. +             char_u    *conv_line = NULL;
  672. +             char_u    *lbuf_line = lbuf;
  673. +             if (vimconv.vc_type != CONV_NONE)
  674. +             {
  675. +             /* Convert the tag line from the encoding of the tags
  676. +              * file to 'encoding'.  Then parse the line again. */
  677. +             conv_line = string_convert(&vimconv, lbuf, NULL);
  678. +             if (conv_line != NULL)
  679. +             {
  680. +                 if (parse_tag_line(conv_line,
  681. + #ifdef FEAT_EMACS_TAGS
  682. +                     is_etag,
  683. + #endif
  684. +                     &tagp) == OK)
  685. +                 lbuf_line = conv_line;
  686. +                 else
  687. +                 /* doesn't work, go back to unconverted line. */
  688. +                 (void)parse_tag_line(lbuf,
  689. + #ifdef FEAT_EMACS_TAGS
  690. +                              is_etag,
  691. + #endif
  692. +                              &tagp);
  693. +             }
  694. +             }
  695. + #else
  696. + # define lbuf_line lbuf
  697. + #endif
  698.               if (help_only)
  699.               {
  700.   #ifdef FEAT_MULTI_LANG
  701. ***************
  702. *** 2019,2025 ****
  703.                * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
  704.                * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
  705.                */
  706. !             len = (int)STRLEN(tag_fname) + (int)STRLEN(lbuf) + 3;
  707.   #ifdef FEAT_EMACS_TAGS
  708.               if (is_etag)
  709.                   len += (int)STRLEN(ebuf) + 1;
  710. --- 2113,2119 ----
  711.                * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
  712.                * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
  713.                */
  714. !             len = (int)STRLEN(tag_fname) + (int)STRLEN(lbuf_line) + 3;
  715.   #ifdef FEAT_EMACS_TAGS
  716.               if (is_etag)
  717.                   len += (int)STRLEN(ebuf) + 1;
  718. ***************
  719. *** 2049,2055 ****
  720.                   else
  721.                   *s++ = NUL;
  722.   #endif
  723. !                 STRCPY(s, lbuf);
  724.               }
  725.               }
  726.   
  727. --- 2143,2149 ----
  728.                   else
  729.                   *s++ = NUL;
  730.   #endif
  731. !                 STRCPY(s, lbuf_line);
  732.               }
  733.               }
  734.   
  735. ***************
  736. *** 2086,2091 ****
  737. --- 2180,2189 ----
  738.               else
  739.                   vim_free(mfp);
  740.               }
  741. + #ifdef FEAT_MBYTE
  742. +             /* Note: this makes the values in "tagp" invalid! */
  743. +             vim_free(conv_line);
  744. + #endif
  745.           }
  746.           else    /* Out of memory! Just forget about the rest. */
  747.           {
  748. ***************
  749. *** 2123,2128 ****
  750. --- 2221,2238 ----
  751.           vim_free(incstack[incstack_idx].etag_fname);
  752.       }
  753.   #endif
  754. + #ifdef FEAT_MBYTE
  755. +     if (pats == &convpat)
  756. +     {
  757. +         /* Go back from converted pattern to original pattern. */
  758. +         vim_free(pats->pat);
  759. +         vim_free(pats->regmatch.regprog);
  760. +         orgpat.regmatch.rm_ic = pats->regmatch.rm_ic;
  761. +         pats = &orgpat;
  762. +     }
  763. +     if (vimconv.vc_type != CONV_NONE)
  764. +         convert_setup(&vimconv, NULL, NULL);
  765. + #endif
  766.   
  767.   #ifdef FEAT_TAG_BINS
  768.       if (sort_error)
  769. ***************
  770. *** 2154,2166 ****
  771.         /* stop searching when already did a linear search, or when
  772.          * TAG_NOIC used, and 'ignorecase' not set
  773.          * or already did case-ignore search */
  774. !       if (stop_searching || linear || (!p_ic && noic) || regmatch.rm_ic)
  775.         break;
  776.   # ifdef FEAT_CSCOPE
  777.         if (use_cscope)
  778.         break;
  779.   # endif
  780. !       regmatch.rm_ic = TRUE;    /* try another time while ignoring case */
  781.       }
  782.   #endif
  783.   
  784. --- 2264,2276 ----
  785.         /* stop searching when already did a linear search, or when
  786.          * TAG_NOIC used, and 'ignorecase' not set
  787.          * or already did case-ignore search */
  788. !       if (stop_searching || linear || (!p_ic && noic) || pats->regmatch.rm_ic)
  789.         break;
  790.   # ifdef FEAT_CSCOPE
  791.         if (use_cscope)
  792.         break;
  793.   # endif
  794. !       pats->regmatch.rm_ic = TRUE;    /* try another time while ignoring case */
  795.       }
  796.   #endif
  797.   
  798. ***************
  799. *** 2173,2179 ****
  800.   
  801.   findtag_end:
  802.       vim_free(lbuf);
  803. !     vim_free(regmatch.regprog);
  804.       vim_free(tag_fname);
  805.   #ifdef FEAT_EMACS_TAGS
  806.       vim_free(ebuf);
  807. --- 2283,2289 ----
  808.   
  809.   findtag_end:
  810.       vim_free(lbuf);
  811. !     vim_free(pats->regmatch.regprog);
  812.       vim_free(tag_fname);
  813.   #ifdef FEAT_EMACS_TAGS
  814.       vim_free(ebuf);
  815. *** ../vim-6.2.510/src/version.c    Wed Apr 28 16:14:57 2004
  816. --- src/version.c    Wed Apr 28 16:17:12 2004
  817. ***************
  818. *** 639,640 ****
  819. --- 639,642 ----
  820.   {   /* Add new patch number below this line */
  821. + /**/
  822. +     511,
  823.   /**/
  824.  
  825. -- 
  826. The future isn't what it used to be.
  827.  
  828.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  829. ///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  830. \\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
  831.  \\\  Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///
  832.