comparison src/os_unix.c @ 444:d0d15b184c56

updated for version 7.0116
author vimboss
date Mon, 25 Jul 2005 20:42:36 +0000
parents 7290ddc7ba55
children a5fcf36ef512
comparison
equal deleted inserted replaced
443:43bf0bcf2110 444:d0d15b184c56
172 static int have_wildcard __ARGS((int, char_u **)); 172 static int have_wildcard __ARGS((int, char_u **));
173 static int have_dollars __ARGS((int, char_u **)); 173 static int have_dollars __ARGS((int, char_u **));
174 #endif 174 #endif
175 175
176 #ifndef NO_EXPANDPATH 176 #ifndef NO_EXPANDPATH
177 static int pstrcmp __ARGS((const void *, const void *));
178 static int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags));
179 # if defined(MACOS_X) && defined(FEAT_MBYTE) 177 # if defined(MACOS_X) && defined(FEAT_MBYTE)
180 extern char_u *mac_precompose_path __ARGS((char_u *decompPath, size_t decompLen, size_t *precompLen)); 178 extern char_u *mac_precompose_path __ARGS((char_u *decompPath, size_t decompLen, size_t *precompLen));
181 # endif 179 # endif
182 #endif 180 #endif
183 181
4733 } 4731 }
4734 4732
4735 #ifndef VMS 4733 #ifndef VMS
4736 4734
4737 #ifndef NO_EXPANDPATH 4735 #ifndef NO_EXPANDPATH
4738 static int 4736 /*
4739 pstrcmp(a, b) 4737 * Expand a path into all matching files and/or directories. Handles "*",
4740 const void *a, *b; 4738 * "?", "[a-z]", "**", etc.
4741 { 4739 * "path" has backslashes before chars that are not to be expanded.
4742 return (pathcmp(*(char **)a, *(char **)b, -1)); 4740 * Returns the number of matches found.
4743 }
4744
4745 /*
4746 * Recursively expand one path component into all matching files and/or
4747 * directories.
4748 * "path" has backslashes before chars that are not to be expanded, starting
4749 * at "path + wildoff".
4750 * Return the number of matches found.
4751 */ 4741 */
4752 int 4742 int
4753 mch_expandpath(gap, path, flags) 4743 mch_expandpath(gap, path, flags)
4754 garray_T *gap; 4744 garray_T *gap;
4755 char_u *path; 4745 char_u *path;
4756 int flags; /* EW_* flags */ 4746 int flags; /* EW_* flags */
4757 { 4747 {
4758 return unix_expandpath(gap, path, 0, flags); 4748 return unix_expandpath(gap, path, 0, flags, FALSE);
4759 }
4760
4761 static int
4762 unix_expandpath(gap, path, wildoff, flags)
4763 garray_T *gap;
4764 char_u *path;
4765 int wildoff;
4766 int flags; /* EW_* flags */
4767 {
4768 char_u *buf;
4769 char_u *path_end;
4770 char_u *p, *s, *e;
4771 int start_len, c;
4772 char_u *pat;
4773 DIR *dirp;
4774 regmatch_T regmatch;
4775 struct dirent *dp;
4776 int starts_with_dot;
4777 int matches;
4778 int len;
4779
4780 start_len = gap->ga_len;
4781 buf = alloc(STRLEN(path) + BASENAMELEN + 5);/* make room for file name */
4782 if (buf == NULL)
4783 return 0;
4784
4785 /*
4786 * Find the first part in the path name that contains a wildcard.
4787 * Copy it into buf, including the preceding characters.
4788 */
4789 p = buf;
4790 s = buf;
4791 e = NULL;
4792 path_end = path;
4793 while (*path_end != NUL)
4794 {
4795 /* May ignore a wildcard that has a backslash before it; it will
4796 * be removed by rem_backslash() or file_pat_to_reg_pat() below. */
4797 if (path_end >= path + wildoff && rem_backslash(path_end))
4798 *p++ = *path_end++;
4799 else if (*path_end == '/')
4800 {
4801 if (e != NULL)
4802 break;
4803 s = p + 1;
4804 }
4805 else if (path_end >= path + wildoff
4806 && vim_strchr((char_u *)"*?[{~$", *path_end) != NULL)
4807 e = p;
4808 #ifdef FEAT_MBYTE
4809 if (has_mbyte)
4810 {
4811 len = (*mb_ptr2len_check)(path_end);
4812 STRNCPY(p, path_end, len);
4813 p += len;
4814 path_end += len;
4815 }
4816 else
4817 #endif
4818 *p++ = *path_end++;
4819 }
4820 e = p;
4821 *e = NUL;
4822
4823 /* now we have one wildcard component between s and e */
4824 /* Remove backslashes between "wildoff" and the start of the wildcard
4825 * component. */
4826 for (p = buf + wildoff; p < s; ++p)
4827 if (rem_backslash(p))
4828 {
4829 STRCPY(p, p + 1);
4830 --e;
4831 --s;
4832 }
4833
4834 /* convert the file pattern to a regexp pattern */
4835 starts_with_dot = (*s == '.');
4836 pat = file_pat_to_reg_pat(s, e, NULL, FALSE);
4837 if (pat == NULL)
4838 {
4839 vim_free(buf);
4840 return 0;
4841 }
4842
4843 /* compile the regexp into a program */
4844 #ifdef MACOS_X /* Can/Should we use CASE_INSENSITIVE_FILENAME instead ?*/
4845 regmatch.rm_ic = TRUE; /* Behave like Terminal.app */
4846 #else
4847 regmatch.rm_ic = FALSE; /* Don't ever ignore case */
4848 #endif
4849 regmatch.regprog = vim_regcomp(pat, RE_MAGIC);
4850 vim_free(pat);
4851
4852 if (regmatch.regprog == NULL)
4853 {
4854 vim_free(buf);
4855 return 0;
4856 }
4857
4858 /* open the directory for scanning */
4859 c = *s;
4860 *s = NUL;
4861 dirp = opendir(*buf == NUL ? "." : (char *)buf);
4862 *s = c;
4863
4864 /* Find all matching entries */
4865 if (dirp != NULL)
4866 {
4867 for (;;)
4868 {
4869 dp = readdir(dirp);
4870 if (dp == NULL)
4871 break;
4872 if ((dp->d_name[0] != '.' || starts_with_dot)
4873 && vim_regexec(&regmatch, (char_u *)dp->d_name, (colnr_T)0))
4874 {
4875 STRCPY(s, dp->d_name);
4876 len = STRLEN(buf);
4877 STRCPY(buf + len, path_end);
4878 if (mch_has_exp_wildcard(path_end)) /* handle more wildcards */
4879 {
4880 /* need to expand another component of the path */
4881 /* remove backslashes for the remaining components only */
4882 (void)unix_expandpath(gap, buf, len + 1, flags);
4883 }
4884 else
4885 {
4886 /* no more wildcards, check if there is a match */
4887 /* remove backslashes for the remaining components only */
4888 if (*path_end != NUL)
4889 backslash_halve(buf + len + 1);
4890 if (mch_getperm(buf) >= 0) /* add existing file */
4891 {
4892 #if defined(MACOS_X) && defined(FEAT_MBYTE)
4893 size_t precomp_len = STRLEN(buf)+1;
4894 char_u *precomp_buf =
4895 mac_precompose_path(buf, precomp_len, &precomp_len);
4896 if (precomp_buf)
4897 {
4898 mch_memmove(buf, precomp_buf, precomp_len);
4899 vim_free(precomp_buf);
4900 }
4901 #endif
4902 addfile(gap, buf, flags);
4903 }
4904 }
4905 }
4906 }
4907
4908 closedir(dirp);
4909 }
4910
4911 vim_free(buf);
4912 vim_free(regmatch.regprog);
4913
4914 matches = gap->ga_len - start_len;
4915 if (matches > 0)
4916 qsort(((char_u **)gap->ga_data) + start_len, matches,
4917 sizeof(char_u *), pstrcmp);
4918 return matches;
4919 } 4749 }
4920 #endif 4750 #endif
4921 4751
4922 /* 4752 /*
4923 * mch_expand_wildcards() - this code does wild-card pattern matching using 4753 * mch_expand_wildcards() - this code does wild-card pattern matching using