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