diff options
Diffstat (limited to 'data/vim/patches/8.1.1099')
-rw-r--r-- | data/vim/patches/8.1.1099 | 1326 |
1 files changed, 0 insertions, 1326 deletions
diff --git a/data/vim/patches/8.1.1099 b/data/vim/patches/8.1.1099 deleted file mode 100644 index 9aa426928..000000000 --- a/data/vim/patches/8.1.1099 +++ /dev/null @@ -1,1326 +0,0 @@ -To: vim_dev@googlegroups.com -Subject: Patch 8.1.1099 -Fcc: outbox -From: Bram Moolenaar <Bram@moolenaar.net> -Mime-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit ------------- - -Patch 8.1.1099 -Problem: The do_tag() function is too long. -Solution: Factor parts out to separate functions. Move simplify_filename() - to a file where it fits better. (Andy Massimino, closes #4195) -Files: src/tag.c, src/proto/tag.pro, src/findfile.c, - src/proto/findfile.pro - - -*** ../vim-8.1.1098/src/tag.c 2019-03-30 21:41:44.218279831 +0100 ---- src/tag.c 2019-03-31 19:14:18.988597395 +0200 -*************** -*** 74,79 **** ---- 74,83 ---- - static int test_for_current(char_u *, char_u *, char_u *, char_u *); - #endif - static int find_extra(char_u **pp); -+ static void print_tag_list(int new_tag, int use_tagstack, int num_matches, char_u **matches); -+ #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) -+ static int add_llist_tags(char_u *tag, int num_matches, char_u **matches); -+ #endif - - static char_u *bottommsg = (char_u *)N_("E555: at bottom of tag stack"); - static char_u *topmsg = (char_u *)N_("E556: at top of tag stack"); -*************** -*** 125,149 **** - int prevtagstackidx = tagstackidx; - int prev_num_matches; - int new_tag = FALSE; -! int other_name; -! int i, j, k; -! int idx; - int ic; -- char_u *p; -- char_u *name; - int no_regexp = FALSE; - int error_cur_match = 0; -- char_u *command_end; - int save_pos = FALSE; - fmark_T saved_fmark; -- int taglen; - #ifdef FEAT_CSCOPE - int jumped_to_tag = FALSE; - #endif -- tagptrs_T tagp, tagp2; - int new_num_matches; - char_u **new_matches; -- int attr; - int use_tagstack; - int skip_msg = FALSE; - char_u *buf_ffname = curbuf->b_ffname; /* name to use for ---- 129,145 ---- - int prevtagstackidx = tagstackidx; - int prev_num_matches; - int new_tag = FALSE; -! int i; - int ic; - int no_regexp = FALSE; - int error_cur_match = 0; - int save_pos = FALSE; - fmark_T saved_fmark; - #ifdef FEAT_CSCOPE - int jumped_to_tag = FALSE; - #endif - int new_num_matches; - char_u **new_matches; - int use_tagstack; - int skip_msg = FALSE; - char_u *buf_ffname = curbuf->b_ffname; /* name to use for -*************** -*** 482,487 **** ---- 478,486 ---- - */ - for (;;) - { -+ int other_name; -+ char_u *name; -+ - /* - * When desired match not found yet, try to find it (and others). - */ -*************** -*** 541,549 **** - * ":tnext" and jumping to another file. */ - if (!new_tag && !other_name) - { - /* Find the position of each old match in the new list. Need - * to use parse_match() to find the tag line. */ -- idx = 0; - for (j = 0; j < num_matches; ++j) - { - parse_match(matches[j], &tagp); ---- 540,551 ---- - * ":tnext" and jumping to another file. */ - if (!new_tag && !other_name) - { -+ int j, k; -+ int idx = 0; -+ tagptrs_T tagp, tagp2; -+ - /* Find the position of each old match in the new list. Need - * to use parse_match() to find the tag line. */ - for (j = 0; j < num_matches; ++j) - { - parse_match(matches[j], &tagp); -*************** -*** 552,558 **** - parse_match(new_matches[i], &tagp2); - if (STRCMP(tagp.tagname, tagp2.tagname) == 0) - { -! p = new_matches[i]; - for (k = i; k > idx; --k) - new_matches[k] = new_matches[k - 1]; - new_matches[idx++] = p; ---- 554,560 ---- - parse_match(new_matches[i], &tagp2); - if (STRCMP(tagp.tagname, tagp2.tagname) == 0) - { -! char_u *p = new_matches[i]; - for (k = i; k > idx; --k) - new_matches[k] = new_matches[k - 1]; - new_matches[idx++] = p; -*************** -*** 587,927 **** - else - #endif - if (type == DT_TAG && *tag != NUL) -! /* -! * If a count is supplied to the ":tag <name>" command, then -! * jump to count'th matching tag. -! */ - cur_match = count > 0 ? count - 1 : 0; - else if (type == DT_SELECT || (type == DT_JUMP && num_matches > 1)) - { -! /* -! * List all the matching tags. -! * Assume that the first match indicates how long the tags can -! * be, and align the file names to that. -! */ -! parse_match(matches[0], &tagp); -! taglen = (int)(tagp.tagname_end - tagp.tagname + 2); -! if (taglen < 18) -! taglen = 18; -! if (taglen > Columns - 25) -! taglen = MAXCOL; -! if (msg_col == 0) -! msg_didout = FALSE; /* overwrite previous message */ -! msg_start(); -! msg_puts_attr(_(" # pri kind tag"), HL_ATTR(HLF_T)); -! msg_clr_eos(); -! taglen_advance(taglen); -! msg_puts_attr(_("file\n"), HL_ATTR(HLF_T)); -! -! for (i = 0; i < num_matches && !got_int; ++i) -! { -! parse_match(matches[i], &tagp); -! if (!new_tag && ( -! #if defined(FEAT_QUICKFIX) -! (g_do_tagpreview != 0 -! && i == ptag_entry.cur_match) || -! #endif -! (use_tagstack -! && i == tagstack[tagstackidx].cur_match))) -! *IObuff = '>'; -! else -! *IObuff = ' '; -! vim_snprintf((char *)IObuff + 1, IOSIZE - 1, -! "%2d %s ", i + 1, -! mt_names[matches[i][0] & MT_MASK]); -! msg_puts((char *)IObuff); -! if (tagp.tagkind != NULL) -! msg_outtrans_len(tagp.tagkind, -! (int)(tagp.tagkind_end - tagp.tagkind)); -! msg_advance(13); -! msg_outtrans_len_attr(tagp.tagname, -! (int)(tagp.tagname_end - tagp.tagname), -! HL_ATTR(HLF_T)); -! msg_putchar(' '); -! taglen_advance(taglen); -! -! /* Find out the actual file name. If it is long, truncate -! * it and put "..." in the middle */ -! p = tag_full_fname(&tagp); -! if (p != NULL) -! { -! msg_outtrans_long_attr(p, HL_ATTR(HLF_D)); -! vim_free(p); -! } -! if (msg_col > 0) -! msg_putchar('\n'); -! if (got_int) -! break; -! msg_advance(15); -! -! /* print any extra fields */ -! command_end = tagp.command_end; -! if (command_end != NULL) -! { -! p = command_end + 3; -! while (*p && *p != '\r' && *p != '\n') -! { -! while (*p == TAB) -! ++p; -! -! /* skip "file:" without a value (static tag) */ -! if (STRNCMP(p, "file:", 5) == 0 -! && vim_isspace(p[5])) -! { -! p += 5; -! continue; -! } -! /* skip "kind:<kind>" and "<kind>" */ -! if (p == tagp.tagkind -! || (p + 5 == tagp.tagkind -! && STRNCMP(p, "kind:", 5) == 0)) -! { -! p = tagp.tagkind_end; -! continue; -! } -! /* print all other extra fields */ -! attr = HL_ATTR(HLF_CM); -! while (*p && *p != '\r' && *p != '\n') -! { -! if (msg_col + ptr2cells(p) >= Columns) -! { -! msg_putchar('\n'); -! if (got_int) -! break; -! msg_advance(15); -! } -! p = msg_outtrans_one(p, attr); -! if (*p == TAB) -! { -! msg_puts_attr(" ", attr); -! break; -! } -! if (*p == ':') -! attr = 0; -! } -! } -! if (msg_col > 15) -! { -! msg_putchar('\n'); -! if (got_int) -! break; -! msg_advance(15); -! } -! } -! else -! { -! for (p = tagp.command; -! *p && *p != '\r' && *p != '\n'; ++p) -! ; -! command_end = p; -! } -! -! /* -! * Put the info (in several lines) at column 15. -! * Don't display "/^" and "?^". -! */ -! p = tagp.command; -! if (*p == '/' || *p == '?') -! { -! ++p; -! if (*p == '^') -! ++p; -! } -! /* Remove leading whitespace from pattern */ -! while (p != command_end && vim_isspace(*p)) -! ++p; -! -! while (p != command_end) -! { -! if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) -! msg_putchar('\n'); -! if (got_int) -! break; -! msg_advance(15); -! -! /* skip backslash used for escaping a command char or -! * a backslash */ -! if (*p == '\\' && (*(p + 1) == *tagp.command -! || *(p + 1) == '\\')) -! ++p; -! -! if (*p == TAB) -! { -! msg_putchar(' '); -! ++p; -! } -! else -! p = msg_outtrans_one(p, 0); -! -! /* don't display the "$/;\"" and "$?;\"" */ -! if (p == command_end - 2 && *p == '$' -! && *(p + 1) == *tagp.command) -! break; -! /* don't display matching '/' or '?' */ -! if (p == command_end - 1 && *p == *tagp.command -! && (*p == '/' || *p == '?')) -! break; -! } -! if (msg_col) -! msg_putchar('\n'); -! ui_breakcheck(); -! } -! if (got_int) -! got_int = FALSE; /* only stop the listing */ - ask_for_selection = TRUE; - } - #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) - else if (type == DT_LTAG) - { -! list_T *list; -! char_u tag_name[128 + 1]; -! char_u *fname; -! char_u *cmd; -! -! /* -! * Add the matching tags to the location list for the current -! * window. -! */ -! -! fname = alloc(MAXPATHL + 1); -! cmd = alloc(CMDBUFFSIZE + 1); -! list = list_alloc(); -! if (list == NULL || fname == NULL || cmd == NULL) -! { -! vim_free(cmd); -! vim_free(fname); -! if (list != NULL) -! list_free(list); - goto end_do_tag; -- } -- -- for (i = 0; i < num_matches; ++i) -- { -- int len, cmd_len; -- long lnum; -- dict_T *dict; -- -- parse_match(matches[i], &tagp); -- -- /* Save the tag name */ -- len = (int)(tagp.tagname_end - tagp.tagname); -- if (len > 128) -- len = 128; -- vim_strncpy(tag_name, tagp.tagname, len); -- tag_name[len] = NUL; -- -- /* Save the tag file name */ -- p = tag_full_fname(&tagp); -- if (p == NULL) -- continue; -- vim_strncpy(fname, p, MAXPATHL); -- vim_free(p); -- -- /* -- * Get the line number or the search pattern used to locate -- * the tag. -- */ -- lnum = 0; -- if (isdigit(*tagp.command)) -- /* Line number is used to locate the tag */ -- lnum = atol((char *)tagp.command); -- else -- { -- char_u *cmd_start, *cmd_end; -- -- /* Search pattern is used to locate the tag */ -- -- /* Locate the end of the command */ -- cmd_start = tagp.command; -- cmd_end = tagp.command_end; -- if (cmd_end == NULL) -- { -- for (p = tagp.command; -- *p && *p != '\r' && *p != '\n'; ++p) -- ; -- cmd_end = p; -- } -- -- /* -- * Now, cmd_end points to the character after the -- * command. Adjust it to point to the last -- * character of the command. -- */ -- cmd_end--; -- -- /* -- * Skip the '/' and '?' characters at the -- * beginning and end of the search pattern. -- */ -- if (*cmd_start == '/' || *cmd_start == '?') -- cmd_start++; -- -- if (*cmd_end == '/' || *cmd_end == '?') -- cmd_end--; -- -- len = 0; -- cmd[0] = NUL; -- -- /* -- * If "^" is present in the tag search pattern, then -- * copy it first. -- */ -- if (*cmd_start == '^') -- { -- STRCPY(cmd, "^"); -- cmd_start++; -- len++; -- } -- -- /* -- * Precede the tag pattern with \V to make it very -- * nomagic. -- */ -- STRCAT(cmd, "\\V"); -- len += 2; -- -- cmd_len = (int)(cmd_end - cmd_start + 1); -- if (cmd_len > (CMDBUFFSIZE - 5)) -- cmd_len = CMDBUFFSIZE - 5; -- STRNCAT(cmd, cmd_start, cmd_len); -- len += cmd_len; -- -- if (cmd[len - 1] == '$') -- { -- /* -- * Replace '$' at the end of the search pattern -- * with '\$' -- */ -- cmd[len - 1] = '\\'; -- cmd[len] = '$'; -- len++; -- } -- -- cmd[len] = NUL; -- } -- -- if ((dict = dict_alloc()) == NULL) -- continue; -- if (list_append_dict(list, dict) == FAIL) -- { -- vim_free(dict); -- continue; -- } -- -- dict_add_string(dict, "text", tag_name); -- dict_add_string(dict, "filename", fname); -- dict_add_number(dict, "lnum", lnum); -- if (lnum == 0) -- dict_add_string(dict, "pattern", cmd); -- } -- -- vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag); -- set_errorlist(curwin, list, ' ', IObuff, NULL); -- -- list_free(list); -- vim_free(fname); -- vim_free(cmd); -- - cur_match = 0; /* Jump to the first tag */ - } - #endif ---- 589,607 ---- - else - #endif - if (type == DT_TAG && *tag != NUL) -! // If a count is supplied to the ":tag <name>" command, then -! // jump to count'th matching tag. - cur_match = count > 0 ? count - 1 : 0; - else if (type == DT_SELECT || (type == DT_JUMP && num_matches > 1)) - { -! print_tag_list(new_tag, use_tagstack, num_matches, matches); - ask_for_selection = TRUE; - } - #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) - else if (type == DT_LTAG) - { -! if (add_llist_tags(tag, num_matches, matches) == FAIL) - goto end_do_tag; - cur_match = 0; /* Jump to the first tag */ - } - #endif -*************** -*** 1089,1094 **** ---- 769,1116 ---- - } - - /* -+ * List all the matching tags. -+ */ -+ static void -+ print_tag_list( -+ int new_tag, -+ int use_tagstack, -+ int num_matches, -+ char_u **matches) -+ { -+ taggy_T *tagstack = curwin->w_tagstack; -+ int tagstackidx = curwin->w_tagstackidx; -+ int i; -+ char_u *p; -+ char_u *command_end; -+ tagptrs_T tagp; -+ int taglen; -+ int attr; -+ -+ /* -+ * Assume that the first match indicates how long the tags can -+ * be, and align the file names to that. -+ */ -+ parse_match(matches[0], &tagp); -+ taglen = (int)(tagp.tagname_end - tagp.tagname + 2); -+ if (taglen < 18) -+ taglen = 18; -+ if (taglen > Columns - 25) -+ taglen = MAXCOL; -+ if (msg_col == 0) -+ msg_didout = FALSE; // overwrite previous message -+ msg_start(); -+ msg_puts_attr(_(" # pri kind tag"), HL_ATTR(HLF_T)); -+ msg_clr_eos(); -+ taglen_advance(taglen); -+ msg_puts_attr(_("file\n"), HL_ATTR(HLF_T)); -+ -+ for (i = 0; i < num_matches && !got_int; ++i) -+ { -+ parse_match(matches[i], &tagp); -+ if (!new_tag && ( -+ #if defined(FEAT_QUICKFIX) -+ (g_do_tagpreview != 0 -+ && i == ptag_entry.cur_match) || -+ #endif -+ (use_tagstack -+ && i == tagstack[tagstackidx].cur_match))) -+ *IObuff = '>'; -+ else -+ *IObuff = ' '; -+ vim_snprintf((char *)IObuff + 1, IOSIZE - 1, -+ "%2d %s ", i + 1, -+ mt_names[matches[i][0] & MT_MASK]); -+ msg_puts((char *)IObuff); -+ if (tagp.tagkind != NULL) -+ msg_outtrans_len(tagp.tagkind, -+ (int)(tagp.tagkind_end - tagp.tagkind)); -+ msg_advance(13); -+ msg_outtrans_len_attr(tagp.tagname, -+ (int)(tagp.tagname_end - tagp.tagname), -+ HL_ATTR(HLF_T)); -+ msg_putchar(' '); -+ taglen_advance(taglen); -+ -+ // Find out the actual file name. If it is long, truncate -+ // it and put "..." in the middle -+ p = tag_full_fname(&tagp); -+ if (p != NULL) -+ { -+ msg_outtrans_long_attr(p, HL_ATTR(HLF_D)); -+ vim_free(p); -+ } -+ if (msg_col > 0) -+ msg_putchar('\n'); -+ if (got_int) -+ break; -+ msg_advance(15); -+ -+ // print any extra fields -+ command_end = tagp.command_end; -+ if (command_end != NULL) -+ { -+ p = command_end + 3; -+ while (*p && *p != '\r' && *p != '\n') -+ { -+ while (*p == TAB) -+ ++p; -+ -+ // skip "file:" without a value (static tag) -+ if (STRNCMP(p, "file:", 5) == 0 -+ && vim_isspace(p[5])) -+ { -+ p += 5; -+ continue; -+ } -+ // skip "kind:<kind>" and "<kind>" -+ if (p == tagp.tagkind -+ || (p + 5 == tagp.tagkind -+ && STRNCMP(p, "kind:", 5) == 0)) -+ { -+ p = tagp.tagkind_end; -+ continue; -+ } -+ // print all other extra fields -+ attr = HL_ATTR(HLF_CM); -+ while (*p && *p != '\r' && *p != '\n') -+ { -+ if (msg_col + ptr2cells(p) >= Columns) -+ { -+ msg_putchar('\n'); -+ if (got_int) -+ break; -+ msg_advance(15); -+ } -+ p = msg_outtrans_one(p, attr); -+ if (*p == TAB) -+ { -+ msg_puts_attr(" ", attr); -+ break; -+ } -+ if (*p == ':') -+ attr = 0; -+ } -+ } -+ if (msg_col > 15) -+ { -+ msg_putchar('\n'); -+ if (got_int) -+ break; -+ msg_advance(15); -+ } -+ } -+ else -+ { -+ for (p = tagp.command; -+ *p && *p != '\r' && *p != '\n'; ++p) -+ ; -+ command_end = p; -+ } -+ -+ // Put the info (in several lines) at column 15. -+ // Don't display "/^" and "?^". -+ p = tagp.command; -+ if (*p == '/' || *p == '?') -+ { -+ ++p; -+ if (*p == '^') -+ ++p; -+ } -+ // Remove leading whitespace from pattern -+ while (p != command_end && vim_isspace(*p)) -+ ++p; -+ -+ while (p != command_end) -+ { -+ if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) -+ msg_putchar('\n'); -+ if (got_int) -+ break; -+ msg_advance(15); -+ -+ // skip backslash used for escaping a command char or -+ // a backslash -+ if (*p == '\\' && (*(p + 1) == *tagp.command -+ || *(p + 1) == '\\')) -+ ++p; -+ -+ if (*p == TAB) -+ { -+ msg_putchar(' '); -+ ++p; -+ } -+ else -+ p = msg_outtrans_one(p, 0); -+ -+ // don't display the "$/;\"" and "$?;\"" -+ if (p == command_end - 2 && *p == '$' -+ && *(p + 1) == *tagp.command) -+ break; -+ // don't display matching '/' or '?' -+ if (p == command_end - 1 && *p == *tagp.command -+ && (*p == '/' || *p == '?')) -+ break; -+ } -+ if (msg_col) -+ msg_putchar('\n'); -+ ui_breakcheck(); -+ } -+ if (got_int) -+ got_int = FALSE; // only stop the listing -+ } -+ -+ #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) -+ /* -+ * Add the matching tags to the location list for the current -+ * window. -+ */ -+ static int -+ add_llist_tags( -+ char_u *tag, -+ int num_matches, -+ char_u **matches) -+ { -+ list_T *list; -+ char_u tag_name[128 + 1]; -+ char_u *fname; -+ char_u *cmd; -+ int i; -+ char_u *p; -+ tagptrs_T tagp; -+ -+ fname = alloc(MAXPATHL + 1); -+ cmd = alloc(CMDBUFFSIZE + 1); -+ list = list_alloc(); -+ if (list == NULL || fname == NULL || cmd == NULL) -+ { -+ vim_free(cmd); -+ vim_free(fname); -+ if (list != NULL) -+ list_free(list); -+ return FAIL; -+ } -+ -+ for (i = 0; i < num_matches; ++i) -+ { -+ int len, cmd_len; -+ long lnum; -+ dict_T *dict; -+ -+ parse_match(matches[i], &tagp); -+ -+ /* Save the tag name */ -+ len = (int)(tagp.tagname_end - tagp.tagname); -+ if (len > 128) -+ len = 128; -+ vim_strncpy(tag_name, tagp.tagname, len); -+ tag_name[len] = NUL; -+ -+ // Save the tag file name -+ p = tag_full_fname(&tagp); -+ if (p == NULL) -+ continue; -+ vim_strncpy(fname, p, MAXPATHL); -+ vim_free(p); -+ -+ // Get the line number or the search pattern used to locate -+ // the tag. -+ lnum = 0; -+ if (isdigit(*tagp.command)) -+ // Line number is used to locate the tag -+ lnum = atol((char *)tagp.command); -+ else -+ { -+ char_u *cmd_start, *cmd_end; -+ -+ // Search pattern is used to locate the tag -+ -+ // Locate the end of the command -+ cmd_start = tagp.command; -+ cmd_end = tagp.command_end; -+ if (cmd_end == NULL) -+ { -+ for (p = tagp.command; -+ *p && *p != '\r' && *p != '\n'; ++p) -+ ; -+ cmd_end = p; -+ } -+ -+ // Now, cmd_end points to the character after the -+ // command. Adjust it to point to the last -+ // character of the command. -+ cmd_end--; -+ -+ // Skip the '/' and '?' characters at the -+ // beginning and end of the search pattern. -+ if (*cmd_start == '/' || *cmd_start == '?') -+ cmd_start++; -+ -+ if (*cmd_end == '/' || *cmd_end == '?') -+ cmd_end--; -+ -+ len = 0; -+ cmd[0] = NUL; -+ -+ // If "^" is present in the tag search pattern, then -+ // copy it first. -+ if (*cmd_start == '^') -+ { -+ STRCPY(cmd, "^"); -+ cmd_start++; -+ len++; -+ } -+ -+ // Precede the tag pattern with \V to make it very -+ // nomagic. -+ STRCAT(cmd, "\\V"); -+ len += 2; -+ -+ cmd_len = (int)(cmd_end - cmd_start + 1); -+ if (cmd_len > (CMDBUFFSIZE - 5)) -+ cmd_len = CMDBUFFSIZE - 5; -+ STRNCAT(cmd, cmd_start, cmd_len); -+ len += cmd_len; -+ -+ if (cmd[len - 1] == '$') -+ { -+ // Replace '$' at the end of the search pattern -+ // with '\$' -+ cmd[len - 1] = '\\'; -+ cmd[len] = '$'; -+ len++; -+ } -+ -+ cmd[len] = NUL; -+ } -+ -+ if ((dict = dict_alloc()) == NULL) -+ continue; -+ if (list_append_dict(list, dict) == FAIL) -+ { -+ vim_free(dict); -+ continue; -+ } -+ -+ dict_add_string(dict, "text", tag_name); -+ dict_add_string(dict, "filename", fname); -+ dict_add_number(dict, "lnum", lnum); -+ if (lnum == 0) -+ dict_add_string(dict, "pattern", cmd); -+ } -+ -+ vim_snprintf((char *)IObuff, IOSIZE, "ltag %s", tag); -+ set_errorlist(curwin, list, ' ', IObuff, NULL); -+ -+ list_free(list); -+ vim_free(fname); -+ vim_free(cmd); -+ -+ return OK; -+ } -+ #endif -+ -+ /* - * Free cached tags. - */ - void -*************** -*** 3431,3648 **** - } - - /* -- * Converts a file name into a canonical form. It simplifies a file name into -- * its simplest form by stripping out unneeded components, if any. The -- * resulting file name is simplified in place and will either be the same -- * length as that supplied, or shorter. -- */ -- void -- simplify_filename(char_u *filename) -- { -- #ifndef AMIGA /* Amiga doesn't have "..", it uses "/" */ -- int components = 0; -- char_u *p, *tail, *start; -- int stripping_disabled = FALSE; -- int relative = TRUE; -- -- p = filename; -- #ifdef BACKSLASH_IN_FILENAME -- if (p[1] == ':') /* skip "x:" */ -- p += 2; -- #endif -- -- if (vim_ispathsep(*p)) -- { -- relative = FALSE; -- do -- ++p; -- while (vim_ispathsep(*p)); -- } -- start = p; /* remember start after "c:/" or "/" or "///" */ -- -- do -- { -- /* At this point "p" is pointing to the char following a single "/" -- * or "p" is at the "start" of the (absolute or relative) path name. */ -- #ifdef VMS -- /* VMS allows device:[path] - don't strip the [ in directory */ -- if ((*p == '[' || *p == '<') && p > filename && p[-1] == ':') -- { -- /* :[ or :< composition: vms directory component */ -- ++components; -- p = getnextcomp(p + 1); -- } -- /* allow remote calls as host"user passwd"::device:[path] */ -- else if (p[0] == ':' && p[1] == ':' && p > filename && p[-1] == '"' ) -- { -- /* ":: composition: vms host/passwd component */ -- ++components; -- p = getnextcomp(p + 2); -- } -- else -- #endif -- if (vim_ispathsep(*p)) -- STRMOVE(p, p + 1); /* remove duplicate "/" */ -- else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL)) -- { -- if (p == start && relative) -- p += 1 + (p[1] != NUL); /* keep single "." or leading "./" */ -- else -- { -- /* Strip "./" or ".///". If we are at the end of the file name -- * and there is no trailing path separator, either strip "/." if -- * we are after "start", or strip "." if we are at the beginning -- * of an absolute path name . */ -- tail = p + 1; -- if (p[1] != NUL) -- while (vim_ispathsep(*tail)) -- MB_PTR_ADV(tail); -- else if (p > start) -- --p; /* strip preceding path separator */ -- STRMOVE(p, tail); -- } -- } -- else if (p[0] == '.' && p[1] == '.' && -- (vim_ispathsep(p[2]) || p[2] == NUL)) -- { -- /* Skip to after ".." or "../" or "..///". */ -- tail = p + 2; -- while (vim_ispathsep(*tail)) -- MB_PTR_ADV(tail); -- -- if (components > 0) /* strip one preceding component */ -- { -- int do_strip = FALSE; -- char_u saved_char; -- stat_T st; -- -- /* Don't strip for an erroneous file name. */ -- if (!stripping_disabled) -- { -- /* If the preceding component does not exist in the file -- * system, we strip it. On Unix, we don't accept a symbolic -- * link that refers to a non-existent file. */ -- saved_char = p[-1]; -- p[-1] = NUL; -- #ifdef UNIX -- if (mch_lstat((char *)filename, &st) < 0) -- #else -- if (mch_stat((char *)filename, &st) < 0) -- #endif -- do_strip = TRUE; -- p[-1] = saved_char; -- -- --p; -- /* Skip back to after previous '/'. */ -- while (p > start && !after_pathsep(start, p)) -- MB_PTR_BACK(start, p); -- -- if (!do_strip) -- { -- /* If the component exists in the file system, check -- * that stripping it won't change the meaning of the -- * file name. First get information about the -- * unstripped file name. This may fail if the component -- * to strip is not a searchable directory (but a regular -- * file, for instance), since the trailing "/.." cannot -- * be applied then. We don't strip it then since we -- * don't want to replace an erroneous file name by -- * a valid one, and we disable stripping of later -- * components. */ -- saved_char = *tail; -- *tail = NUL; -- if (mch_stat((char *)filename, &st) >= 0) -- do_strip = TRUE; -- else -- stripping_disabled = TRUE; -- *tail = saved_char; -- #ifdef UNIX -- if (do_strip) -- { -- stat_T new_st; -- -- /* On Unix, the check for the unstripped file name -- * above works also for a symbolic link pointing to -- * a searchable directory. But then the parent of -- * the directory pointed to by the link must be the -- * same as the stripped file name. (The latter -- * exists in the file system since it is the -- * component's parent directory.) */ -- if (p == start && relative) -- (void)mch_stat(".", &new_st); -- else -- { -- saved_char = *p; -- *p = NUL; -- (void)mch_stat((char *)filename, &new_st); -- *p = saved_char; -- } -- -- if (new_st.st_ino != st.st_ino || -- new_st.st_dev != st.st_dev) -- { -- do_strip = FALSE; -- /* We don't disable stripping of later -- * components since the unstripped path name is -- * still valid. */ -- } -- } -- #endif -- } -- } -- -- if (!do_strip) -- { -- /* Skip the ".." or "../" and reset the counter for the -- * components that might be stripped later on. */ -- p = tail; -- components = 0; -- } -- else -- { -- /* Strip previous component. If the result would get empty -- * and there is no trailing path separator, leave a single -- * "." instead. If we are at the end of the file name and -- * there is no trailing path separator and a preceding -- * component is left after stripping, strip its trailing -- * path separator as well. */ -- if (p == start && relative && tail[-1] == '.') -- { -- *p++ = '.'; -- *p = NUL; -- } -- else -- { -- if (p > start && tail[-1] == '.') -- --p; -- STRMOVE(p, tail); /* strip previous component */ -- } -- -- --components; -- } -- } -- else if (p == start && !relative) /* leading "/.." or "/../" */ -- STRMOVE(p, tail); /* strip ".." or "../" */ -- else -- { -- if (p == start + 2 && p[-2] == '.') /* leading "./../" */ -- { -- STRMOVE(p - 2, p); /* strip leading "./" */ -- tail -= 2; -- } -- p = tail; /* skip to char after ".." or "../" */ -- } -- } -- else -- { -- ++components; /* simple path component */ -- p = getnextcomp(p); -- } -- } while (*p != NUL); -- #endif /* !AMIGA */ -- } -- -- /* - * Check if we have a tag for the buffer with name "buf_ffname". - * This is a bit slow, because of the full path compare in fullpathcmp(). - * Return TRUE if tag for file "fname" if tag file "tag_fname" is for current ---- 3453,3458 ---- -*** ../vim-8.1.1098/src/proto/tag.pro 2018-11-11 15:20:32.436704418 +0100 ---- src/proto/tag.pro 2019-03-31 19:09:23.798893253 +0200 -*************** -*** 6,12 **** - void free_tag_stuff(void); - int get_tagfname(tagname_T *tnp, int first, char_u *buf); - void tagname_free(tagname_T *tnp); -- void simplify_filename(char_u *filename); - int expand_tags(int tagnames, char_u *pat, int *num_file, char_u ***file); - int get_tags(list_T *list, char_u *pat, char_u *buf_fname); - void get_tagstack(win_T *wp, dict_T *retdict); ---- 6,11 ---- -*** ../vim-8.1.1098/src/findfile.c 2019-03-09 12:32:50.673562149 +0100 ---- src/findfile.c 2019-03-31 19:09:15.586959263 +0200 -*************** -*** 2605,2607 **** ---- 2605,2819 ---- - } - - #endif // FEAT_SEARCHPATH -+ -+ /* -+ * Converts a file name into a canonical form. It simplifies a file name into -+ * its simplest form by stripping out unneeded components, if any. The -+ * resulting file name is simplified in place and will either be the same -+ * length as that supplied, or shorter. -+ */ -+ void -+ simplify_filename(char_u *filename) -+ { -+ #ifndef AMIGA // Amiga doesn't have "..", it uses "/" -+ int components = 0; -+ char_u *p, *tail, *start; -+ int stripping_disabled = FALSE; -+ int relative = TRUE; -+ -+ p = filename; -+ # ifdef BACKSLASH_IN_FILENAME -+ if (p[1] == ':') // skip "x:" -+ p += 2; -+ # endif -+ -+ if (vim_ispathsep(*p)) -+ { -+ relative = FALSE; -+ do -+ ++p; -+ while (vim_ispathsep(*p)); -+ } -+ start = p; // remember start after "c:/" or "/" or "///" -+ -+ do -+ { -+ // At this point "p" is pointing to the char following a single "/" -+ // or "p" is at the "start" of the (absolute or relative) path name. -+ # ifdef VMS -+ // VMS allows device:[path] - don't strip the [ in directory -+ if ((*p == '[' || *p == '<') && p > filename && p[-1] == ':') -+ { -+ // :[ or :< composition: vms directory component -+ ++components; -+ p = getnextcomp(p + 1); -+ } -+ // allow remote calls as host"user passwd"::device:[path] -+ else if (p[0] == ':' && p[1] == ':' && p > filename && p[-1] == '"' ) -+ { -+ // ":: composition: vms host/passwd component -+ ++components; -+ p = getnextcomp(p + 2); -+ } -+ else -+ # endif -+ if (vim_ispathsep(*p)) -+ STRMOVE(p, p + 1); // remove duplicate "/" -+ else if (p[0] == '.' && (vim_ispathsep(p[1]) || p[1] == NUL)) -+ { -+ if (p == start && relative) -+ p += 1 + (p[1] != NUL); // keep single "." or leading "./" -+ else -+ { -+ // Strip "./" or ".///". If we are at the end of the file name -+ // and there is no trailing path separator, either strip "/." if -+ // we are after "start", or strip "." if we are at the beginning -+ // of an absolute path name . -+ tail = p + 1; -+ if (p[1] != NUL) -+ while (vim_ispathsep(*tail)) -+ MB_PTR_ADV(tail); -+ else if (p > start) -+ --p; // strip preceding path separator -+ STRMOVE(p, tail); -+ } -+ } -+ else if (p[0] == '.' && p[1] == '.' && -+ (vim_ispathsep(p[2]) || p[2] == NUL)) -+ { -+ // Skip to after ".." or "../" or "..///". -+ tail = p + 2; -+ while (vim_ispathsep(*tail)) -+ MB_PTR_ADV(tail); -+ -+ if (components > 0) // strip one preceding component -+ { -+ int do_strip = FALSE; -+ char_u saved_char; -+ stat_T st; -+ -+ /* Don't strip for an erroneous file name. */ -+ if (!stripping_disabled) -+ { -+ // If the preceding component does not exist in the file -+ // system, we strip it. On Unix, we don't accept a symbolic -+ // link that refers to a non-existent file. -+ saved_char = p[-1]; -+ p[-1] = NUL; -+ # ifdef UNIX -+ if (mch_lstat((char *)filename, &st) < 0) -+ # else -+ if (mch_stat((char *)filename, &st) < 0) -+ # endif -+ do_strip = TRUE; -+ p[-1] = saved_char; -+ -+ --p; -+ // Skip back to after previous '/'. -+ while (p > start && !after_pathsep(start, p)) -+ MB_PTR_BACK(start, p); -+ -+ if (!do_strip) -+ { -+ // If the component exists in the file system, check -+ // that stripping it won't change the meaning of the -+ // file name. First get information about the -+ // unstripped file name. This may fail if the component -+ // to strip is not a searchable directory (but a regular -+ // file, for instance), since the trailing "/.." cannot -+ // be applied then. We don't strip it then since we -+ // don't want to replace an erroneous file name by -+ // a valid one, and we disable stripping of later -+ // components. -+ saved_char = *tail; -+ *tail = NUL; -+ if (mch_stat((char *)filename, &st) >= 0) -+ do_strip = TRUE; -+ else -+ stripping_disabled = TRUE; -+ *tail = saved_char; -+ # ifdef UNIX -+ if (do_strip) -+ { -+ stat_T new_st; -+ -+ // On Unix, the check for the unstripped file name -+ // above works also for a symbolic link pointing to -+ // a searchable directory. But then the parent of -+ // the directory pointed to by the link must be the -+ // same as the stripped file name. (The latter -+ // exists in the file system since it is the -+ // component's parent directory.) -+ if (p == start && relative) -+ (void)mch_stat(".", &new_st); -+ else -+ { -+ saved_char = *p; -+ *p = NUL; -+ (void)mch_stat((char *)filename, &new_st); -+ *p = saved_char; -+ } -+ -+ if (new_st.st_ino != st.st_ino || -+ new_st.st_dev != st.st_dev) -+ { -+ do_strip = FALSE; -+ // We don't disable stripping of later -+ // components since the unstripped path name is -+ // still valid. -+ } -+ } -+ # endif -+ } -+ } -+ -+ if (!do_strip) -+ { -+ // Skip the ".." or "../" and reset the counter for the -+ // components that might be stripped later on. -+ p = tail; -+ components = 0; -+ } -+ else -+ { -+ // Strip previous component. If the result would get empty -+ // and there is no trailing path separator, leave a single -+ // "." instead. If we are at the end of the file name and -+ // there is no trailing path separator and a preceding -+ // component is left after stripping, strip its trailing -+ // path separator as well. -+ if (p == start && relative && tail[-1] == '.') -+ { -+ *p++ = '.'; -+ *p = NUL; -+ } -+ else -+ { -+ if (p > start && tail[-1] == '.') -+ --p; -+ STRMOVE(p, tail); // strip previous component -+ } -+ -+ --components; -+ } -+ } -+ else if (p == start && !relative) // leading "/.." or "/../" -+ STRMOVE(p, tail); // strip ".." or "../" -+ else -+ { -+ if (p == start + 2 && p[-2] == '.') // leading "./../" -+ { -+ STRMOVE(p - 2, p); // strip leading "./" -+ tail -= 2; -+ } -+ p = tail; // skip to char after ".." or "../" -+ } -+ } -+ else -+ { -+ ++components; // simple path component -+ p = getnextcomp(p); -+ } -+ } while (*p != NUL); -+ #endif // !AMIGA -+ } -*** ../vim-8.1.1098/src/proto/findfile.pro 2019-02-13 22:45:21.512636158 +0100 ---- src/proto/findfile.pro 2019-03-31 19:09:20.870916772 +0200 -*************** -*** 15,18 **** ---- 15,19 ---- - int vim_ispathlistsep(int c); - void uniquefy_paths(garray_T *gap, char_u *pattern); - int expand_in_path(garray_T *gap, char_u *pattern, int flags); -+ void simplify_filename(char_u *filename); - /* vim: set ft=c : */ -*** ../vim-8.1.1098/src/version.c 2019-03-31 15:31:54.592053004 +0200 ---- src/version.c 2019-03-31 19:39:26.094371299 +0200 -*************** -*** 773,774 **** ---- 773,776 ---- - { /* Add new patch number below this line */ -+ /**/ -+ 1099, - /**/ - --- -hundred-and-one symptoms of being an internet addict: -175. You send yourself e-mail before you go to bed to remind you - what to do when you wake up. - - /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ -/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ -\\\ an exciting new programming language -- http://www.Zimbu.org /// - \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |