aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2001-10-25 13:33:01 +0000
committerEli Zaretskii2001-10-25 13:33:01 +0000
commit4887597a1c52b8277eabeb4d9484c75b1bc9429d (patch)
tree949f97173f3c79e008fc6ea2dba47b9682ba74a0 /src
parentdfe92a6aca66555ae7bb0ca36c5d5d7c12fe91ca (diff)
downloademacs-4887597a1c52b8277eabeb4d9484c75b1bc9429d.tar.gz
emacs-4887597a1c52b8277eabeb4d9484c75b1bc9429d.zip
Revert last change (which removed old commented-out
version of expand-file-name). Add a comment that explains why this old version should not be removed.
Diffstat (limited to 'src')
-rw-r--r--src/fileio.c333
1 files changed, 333 insertions, 0 deletions
diff --git a/src/fileio.c b/src/fileio.c
index d1c35aeddb2..a5c9972692b 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1647,6 +1647,339 @@ See also the function `substitute-in-file-name'. */)
1647 return make_string (target, o - target); 1647 return make_string (target, o - target);
1648} 1648}
1649 1649
1650#if 0
1651/* PLEASE DO NOT DELETE THIS COMMENTED-OUT VERSION!
1652 This is the old version of expand-file-name, before it was thoroughly
1653 rewritten for Emacs 10.31. We leave this version here commented-out,
1654 because the code is very complex and likely to have subtle bugs. If
1655 bugs _are_ found, it might be of interest to look at the old code and
1656 see what did it do in the relevant situation.
1657
1658 Don't remove this code: it's true that it will be accessible via CVS,
1659 but a few years from deletion, people will forget it is there. */
1660
1661/* Changed this DEFUN to a DEAFUN, so as not to confuse `make-docfile'. */
1662DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1663 "Convert FILENAME to absolute, and canonicalize it.\n\
1664Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1665 (does not start with slash); if DEFAULT is nil or missing,\n\
1666the current buffer's value of default-directory is used.\n\
1667Filenames containing `.' or `..' as components are simplified;\n\
1668initial `~/' expands to your home directory.\n\
1669See also the function `substitute-in-file-name'.")
1670 (name, defalt)
1671 Lisp_Object name, defalt;
1672{
1673 unsigned char *nm;
1674
1675 register unsigned char *newdir, *p, *o;
1676 int tlen;
1677 unsigned char *target;
1678 struct passwd *pw;
1679 int lose;
1680#ifdef VMS
1681 unsigned char * colon = 0;
1682 unsigned char * close = 0;
1683 unsigned char * slash = 0;
1684 unsigned char * brack = 0;
1685 int lbrack = 0, rbrack = 0;
1686 int dots = 0;
1687#endif /* VMS */
1688
1689 CHECK_STRING (name, 0);
1690
1691#ifdef VMS
1692 /* Filenames on VMS are always upper case. */
1693 name = Fupcase (name);
1694#endif
1695
1696 nm = XSTRING (name)->data;
1697
1698 /* If nm is absolute, flush ...// and detect /./ and /../.
1699 If no /./ or /../ we can return right away. */
1700 if (
1701 nm[0] == '/'
1702#ifdef VMS
1703 || index (nm, ':')
1704#endif /* VMS */
1705 )
1706 {
1707 p = nm;
1708 lose = 0;
1709 while (*p)
1710 {
1711 if (p[0] == '/' && p[1] == '/'
1712#ifdef APOLLO
1713 /* // at start of filename is meaningful on Apollo system. */
1714 && nm != p
1715#endif /* APOLLO */
1716 )
1717 nm = p + 1;
1718 if (p[0] == '/' && p[1] == '~')
1719 nm = p + 1, lose = 1;
1720 if (p[0] == '/' && p[1] == '.'
1721 && (p[2] == '/' || p[2] == 0
1722 || (p[2] == '.' && (p[3] == '/' || p[3] == 0))))
1723 lose = 1;
1724#ifdef VMS
1725 if (p[0] == '\\')
1726 lose = 1;
1727 if (p[0] == '/') {
1728 /* if dev:[dir]/, move nm to / */
1729 if (!slash && p > nm && (brack || colon)) {
1730 nm = (brack ? brack + 1 : colon + 1);
1731 lbrack = rbrack = 0;
1732 brack = 0;
1733 colon = 0;
1734 }
1735 slash = p;
1736 }
1737 if (p[0] == '-')
1738#ifndef VMS4_4
1739 /* VMS pre V4.4,convert '-'s in filenames. */
1740 if (lbrack == rbrack)
1741 {
1742 if (dots < 2) /* this is to allow negative version numbers */
1743 p[0] = '_';
1744 }
1745 else
1746#endif /* VMS4_4 */
1747 if (lbrack > rbrack &&
1748 ((p[-1] == '.' || p[-1] == '[' || p[-1] == '<') &&
1749 (p[1] == '.' || p[1] == ']' || p[1] == '>')))
1750 lose = 1;
1751#ifndef VMS4_4
1752 else
1753 p[0] = '_';
1754#endif /* VMS4_4 */
1755 /* count open brackets, reset close bracket pointer */
1756 if (p[0] == '[' || p[0] == '<')
1757 lbrack++, brack = 0;
1758 /* count close brackets, set close bracket pointer */
1759 if (p[0] == ']' || p[0] == '>')
1760 rbrack++, brack = p;
1761 /* detect ][ or >< */
1762 if ((p[0] == ']' || p[0] == '>') && (p[1] == '[' || p[1] == '<'))
1763 lose = 1;
1764 if ((p[0] == ':' || p[0] == ']' || p[0] == '>') && p[1] == '~')
1765 nm = p + 1, lose = 1;
1766 if (p[0] == ':' && (colon || slash))
1767 /* if dev1:[dir]dev2:, move nm to dev2: */
1768 if (brack)
1769 {
1770 nm = brack + 1;
1771 brack = 0;
1772 }
1773 /* If /name/dev:, move nm to dev: */
1774 else if (slash)
1775 nm = slash + 1;
1776 /* If node::dev:, move colon following dev */
1777 else if (colon && colon[-1] == ':')
1778 colon = p;
1779 /* If dev1:dev2:, move nm to dev2: */
1780 else if (colon && colon[-1] != ':')
1781 {
1782 nm = colon + 1;
1783 colon = 0;
1784 }
1785 if (p[0] == ':' && !colon)
1786 {
1787 if (p[1] == ':')
1788 p++;
1789 colon = p;
1790 }
1791 if (lbrack == rbrack)
1792 if (p[0] == ';')
1793 dots = 2;
1794 else if (p[0] == '.')
1795 dots++;
1796#endif /* VMS */
1797 p++;
1798 }
1799 if (!lose)
1800 {
1801#ifdef VMS
1802 if (index (nm, '/'))
1803 return build_string (sys_translate_unix (nm));
1804#endif /* VMS */
1805 if (nm == XSTRING (name)->data)
1806 return name;
1807 return build_string (nm);
1808 }
1809 }
1810
1811 /* Now determine directory to start with and put it in NEWDIR */
1812
1813 newdir = 0;
1814
1815 if (nm[0] == '~') /* prefix ~ */
1816 if (nm[1] == '/'
1817#ifdef VMS
1818 || nm[1] == ':'
1819#endif /* VMS */
1820 || nm[1] == 0)/* ~/filename */
1821 {
1822 if (!(newdir = (unsigned char *) egetenv ("HOME")))
1823 newdir = (unsigned char *) "";
1824 nm++;
1825#ifdef VMS
1826 nm++; /* Don't leave the slash in nm. */
1827#endif /* VMS */
1828 }
1829 else /* ~user/filename */
1830 {
1831 /* Get past ~ to user */
1832 unsigned char *user = nm + 1;
1833 /* Find end of name. */
1834 unsigned char *ptr = (unsigned char *) index (user, '/');
1835 int len = ptr ? ptr - user : strlen (user);
1836#ifdef VMS
1837 unsigned char *ptr1 = index (user, ':');
1838 if (ptr1 != 0 && ptr1 - user < len)
1839 len = ptr1 - user;
1840#endif /* VMS */
1841 /* Copy the user name into temp storage. */
1842 o = (unsigned char *) alloca (len + 1);
1843 bcopy ((char *) user, o, len);
1844 o[len] = 0;
1845
1846 /* Look up the user name. */
1847 pw = (struct passwd *) getpwnam (o + 1);
1848 if (!pw)
1849 error ("\"%s\" isn't a registered user", o + 1);
1850
1851 newdir = (unsigned char *) pw->pw_dir;
1852
1853 /* Discard the user name from NM. */
1854 nm += len;
1855 }
1856
1857 if (nm[0] != '/'
1858#ifdef VMS
1859 && !index (nm, ':')
1860#endif /* not VMS */
1861 && !newdir)
1862 {
1863 if (NILP (defalt))
1864 defalt = current_buffer->directory;
1865 CHECK_STRING (defalt, 1);
1866 newdir = XSTRING (defalt)->data;
1867 }
1868
1869 /* Now concatenate the directory and name to new space in the stack frame */
1870
1871 tlen = (newdir ? strlen (newdir) + 1 : 0) + strlen (nm) + 1;
1872 target = (unsigned char *) alloca (tlen);
1873 *target = 0;
1874
1875 if (newdir)
1876 {
1877#ifndef VMS
1878 if (nm[0] == 0 || nm[0] == '/')
1879 strcpy (target, newdir);
1880 else
1881#endif
1882 file_name_as_directory (target, newdir);
1883 }
1884
1885 strcat (target, nm);
1886#ifdef VMS
1887 if (index (target, '/'))
1888 strcpy (target, sys_translate_unix (target));
1889#endif /* VMS */
1890
1891 /* Now canonicalize by removing /. and /foo/.. if they appear */
1892
1893 p = target;
1894 o = target;
1895
1896 while (*p)
1897 {
1898#ifdef VMS
1899 if (*p != ']' && *p != '>' && *p != '-')
1900 {
1901 if (*p == '\\')
1902 p++;
1903 *o++ = *p++;
1904 }
1905 else if ((p[0] == ']' || p[0] == '>') && p[0] == p[1] + 2)
1906 /* brackets are offset from each other by 2 */
1907 {
1908 p += 2;
1909 if (*p != '.' && *p != '-' && o[-1] != '.')
1910 /* convert [foo][bar] to [bar] */
1911 while (o[-1] != '[' && o[-1] != '<')
1912 o--;
1913 else if (*p == '-' && *o != '.')
1914 *--p = '.';
1915 }
1916 else if (p[0] == '-' && o[-1] == '.' &&
1917 (p[1] == '.' || p[1] == ']' || p[1] == '>'))
1918 /* flush .foo.- ; leave - if stopped by '[' or '<' */
1919 {
1920 do
1921 o--;
1922 while (o[-1] != '.' && o[-1] != '[' && o[-1] != '<');
1923 if (p[1] == '.') /* foo.-.bar ==> bar. */
1924 p += 2;
1925 else if (o[-1] == '.') /* '.foo.-]' ==> ']' */
1926 p++, o--;
1927 /* else [foo.-] ==> [-] */
1928 }
1929 else
1930 {
1931#ifndef VMS4_4
1932 if (*p == '-' &&
1933 o[-1] != '[' && o[-1] != '<' && o[-1] != '.' &&
1934 p[1] != ']' && p[1] != '>' && p[1] != '.')
1935 *p = '_';
1936#endif /* VMS4_4 */
1937 *o++ = *p++;
1938 }
1939#else /* not VMS */
1940 if (*p != '/')
1941 {
1942 *o++ = *p++;
1943 }
1944 else if (!strncmp (p, "//", 2)
1945#ifdef APOLLO
1946 /* // at start of filename is meaningful in Apollo system. */
1947 && o != target
1948#endif /* APOLLO */
1949 )
1950 {
1951 o = target;
1952 p++;
1953 }
1954 else if (p[0] == '/' && p[1] == '.' &&
1955 (p[2] == '/' || p[2] == 0))
1956 p += 2;
1957 else if (!strncmp (p, "/..", 3)
1958 /* `/../' is the "superroot" on certain file systems. */
1959 && o != target
1960 && (p[3] == '/' || p[3] == 0))
1961 {
1962 while (o != target && *--o != '/')
1963 ;
1964#ifdef APOLLO
1965 if (o == target + 1 && o[-1] == '/' && o[0] == '/')
1966 ++o;
1967 else
1968#endif /* APOLLO */
1969 if (o == target && *o == '/')
1970 ++o;
1971 p += 3;
1972 }
1973 else
1974 {
1975 *o++ = *p++;
1976 }
1977#endif /* not VMS */
1978 }
1979
1980 return make_string (target, o - target);
1981}
1982#endif
1650 1983
1651DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, 1984DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
1652 Ssubstitute_in_file_name, 1, 1, 0, 1985 Ssubstitute_in_file_name, 1, 1, 0,