aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Schmidt <john.schmidt.h@gmail.com>2014-03-30 22:25:59 +0200
committerThiago de Arruda <tpadilha84@gmail.com>2014-04-01 08:08:07 -0300
commitf5082d0a708d08a9d71fa0f067a4e551ad533f2e (patch)
tree8246f973554c60ae08bf118a811bed9ee2332f45
parent7fd140b99ac1a3762f68f9d24360aecf1330e6e2 (diff)
downloadrneovim-f5082d0a708d08a9d71fa0f067a4e551ad533f2e.tar.gz
rneovim-f5082d0a708d08a9d71fa0f067a4e551ad533f2e.tar.bz2
rneovim-f5082d0a708d08a9d71fa0f067a4e551ad533f2e.zip
Move simplify_filename from tag.c
-rw-r--r--src/path.c169
-rw-r--r--src/path.h1
-rw-r--r--src/tag.c169
-rw-r--r--src/tag.h1
4 files changed, 170 insertions, 170 deletions
diff --git a/src/path.c b/src/path.c
index d1b3dcc05c..517d0fa42a 100644
--- a/src/path.c
+++ b/src/path.c
@@ -1301,3 +1301,172 @@ addfile (
((char_u **)gap->ga_data)[gap->ga_len++] = p;
}
#endif /* !NO_EXPANDPATH */
+
+/*
+ * 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)
+{
+ 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. */
+ 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;
+ struct stat 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) {
+ struct stat 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);
+}
diff --git a/src/path.h b/src/path.h
index cf46b0f02f..a126d1a67e 100644
--- a/src/path.h
+++ b/src/path.h
@@ -22,4 +22,5 @@ char_u *get_past_head(char_u *path);
char_u *concat_str(char_u *str1, char_u *str2);
void add_pathsep(char_u *p);
char_u *FullName_save(char_u *fname, int force);
+void simplify_filename(char_u *filename);
#endif
diff --git a/src/tag.c b/src/tag.c
index 2083226e82..363659dd4a 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -2722,175 +2722,6 @@ static char_u *expand_tag_fname(char_u *fname, char_u *tag_fname, int expand)
}
/*
- * 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)
-{
- 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. */
- 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;
- struct stat 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) {
- struct stat 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);
-}
-
-/*
* 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
diff --git a/src/tag.h b/src/tag.h
index 859174ccc3..72da6e0e19 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -21,7 +21,6 @@ int find_tags(char_u *pat, int *num_matches, char_u ***matchesp,
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);