Mercurial > vim
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(®match, (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 |