Mercurial > hg > xemacs-beta
comparison src/fileio.c @ 4324:5e526366d533
Don't error on unknown environment variables, #'substitute-in-file-name.
SUPERSEDES 18270.47509.666061.606519@parhasard.net
APPROVE COMMIT
src/fileio.c addition:
2007-12-11 Aidan Kehoe <kehoea@parhasard.net>
* fileio.c (Fsubstitute_in_file_name):
On encountering non-existent environment variables or incorrect
syntax for specifying environment variables (as is routine on
Windows) don't error, instead pass the original strings through.
tests/ChangeLog addition:
2007-12-11 Aidan Kehoe <kehoea@parhasard.net>
* automated/syntax-tests.el:
Check that substitute-in-file-name doesn't error when handed
non-existing environment variables, passing through the specified
string instead. Also check that existing environment variables are
correctly substituted. Also check that double slashes in the
middle of a path name are treated as re-starting the path.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Tue, 11 Dec 2007 21:50:22 +0100 |
parents | c5a2b80bc4fa |
children | 1e04b9c8125b |
comparison
equal
deleted
inserted
replaced
4323:94509abd0ef0 | 4324:5e526366d533 |
---|---|
1516 (filename)) | 1516 (filename)) |
1517 { | 1517 { |
1518 /* This function can GC. GC checked 2000-07-28 ben. */ | 1518 /* This function can GC. GC checked 2000-07-28 ben. */ |
1519 Ibyte *nm; | 1519 Ibyte *nm; |
1520 | 1520 |
1521 Ibyte *s, *p, *o, *x, *endp; | 1521 Ibyte *s, *p, *o, *x, *endp, *got; |
1522 Ibyte *target = 0; | 1522 Ibyte *target = 0; |
1523 int total = 0; | 1523 int total = 0; |
1524 int substituted = 0; | 1524 int substituted = 0, seen_braces; |
1525 Ibyte *xnm; | 1525 Ibyte *xnm; |
1526 Lisp_Object handler; | 1526 Lisp_Object handler; |
1527 | 1527 |
1528 CHECK_STRING (filename); | 1528 CHECK_STRING (filename); |
1529 | 1529 |
1574 p++; | 1574 p++; |
1575 else | 1575 else |
1576 { | 1576 { |
1577 p++; | 1577 p++; |
1578 if (p == endp) | 1578 if (p == endp) |
1579 goto badsubst; | 1579 { |
1580 /* No substitution, no error. */ | |
1581 break; | |
1582 } | |
1580 else if (*p == '$') | 1583 else if (*p == '$') |
1581 { | 1584 { |
1582 /* "$$" means a single "$" */ | 1585 /* "$$" means a single "$" */ |
1583 p++; | 1586 p++; |
1584 total -= 1; | 1587 total -= 1; |
1587 } | 1590 } |
1588 else if (*p == '{') | 1591 else if (*p == '{') |
1589 { | 1592 { |
1590 o = ++p; | 1593 o = ++p; |
1591 while (p != endp && *p != '}') p++; | 1594 while (p != endp && *p != '}') p++; |
1592 if (*p != '}') goto missingclose; | 1595 if (*p != '}') |
1596 { | |
1597 /* No substitution, no error. Keep looking. */ | |
1598 p = o; | |
1599 continue; | |
1600 } | |
1593 s = p; | 1601 s = p; |
1594 } | 1602 } |
1595 else | 1603 else |
1596 { | 1604 { |
1597 o = p; | 1605 o = p; |
1606 #ifdef WIN32_NATIVE | 1614 #ifdef WIN32_NATIVE |
1607 qxestrupr (target); /* $home == $HOME etc. */ | 1615 qxestrupr (target); /* $home == $HOME etc. */ |
1608 #endif /* WIN32_NATIVE */ | 1616 #endif /* WIN32_NATIVE */ |
1609 | 1617 |
1610 /* Get variable value */ | 1618 /* Get variable value */ |
1611 o = egetenv ((CIbyte *) target); | 1619 got = egetenv ((CIbyte *) target); |
1612 if (!o) goto badvar; | 1620 if (got) |
1613 total += qxestrlen (o); | 1621 { |
1614 substituted = 1; | 1622 total += qxestrlen (got); |
1623 substituted = 1; | |
1624 } | |
1615 } | 1625 } |
1616 | 1626 |
1617 if (!substituted) | 1627 if (!substituted) |
1618 return filename; | 1628 return filename; |
1619 | 1629 |
1627 if (*p != '$') | 1637 if (*p != '$') |
1628 *x++ = *p++; | 1638 *x++ = *p++; |
1629 else | 1639 else |
1630 { | 1640 { |
1631 p++; | 1641 p++; |
1642 seen_braces = 0; | |
1632 if (p == endp) | 1643 if (p == endp) |
1633 goto badsubst; | 1644 { |
1645 *x++ = '$'; | |
1646 break; | |
1647 } | |
1634 else if (*p == '$') | 1648 else if (*p == '$') |
1635 { | 1649 { |
1636 *x++ = *p++; | 1650 *x++ = *p++; |
1637 continue; | 1651 continue; |
1638 } | 1652 } |
1639 else if (*p == '{') | 1653 else if (*p == '{') |
1640 { | 1654 { |
1655 seen_braces = 1; | |
1641 o = ++p; | 1656 o = ++p; |
1642 while (p != endp && *p != '}') p++; | 1657 while (p != endp && *p != '}') p++; |
1643 if (*p != '}') goto missingclose; | 1658 if (*p != '}') |
1659 { | |
1660 /* Don't syntax error, don't substitute */ | |
1661 *x++ = '{'; | |
1662 p = o; | |
1663 continue; | |
1664 } | |
1644 s = p++; | 1665 s = p++; |
1645 } | 1666 } |
1646 else | 1667 else |
1647 { | 1668 { |
1648 o = p; | 1669 o = p; |
1657 #ifdef WIN32_NATIVE | 1678 #ifdef WIN32_NATIVE |
1658 qxestrupr (target); /* $home == $HOME etc. */ | 1679 qxestrupr (target); /* $home == $HOME etc. */ |
1659 #endif /* WIN32_NATIVE */ | 1680 #endif /* WIN32_NATIVE */ |
1660 | 1681 |
1661 /* Get variable value */ | 1682 /* Get variable value */ |
1662 o = egetenv ((CIbyte *) target); | 1683 got = egetenv ((CIbyte *) target); |
1663 if (!o) | 1684 if (got) |
1664 goto badvar; | 1685 { |
1665 | 1686 qxestrcpy (x, got); |
1666 qxestrcpy (x, o); | 1687 x += qxestrlen (got); |
1667 x += qxestrlen (o); | 1688 } |
1689 else | |
1690 { | |
1691 *x++ = '$'; | |
1692 if (seen_braces) | |
1693 { | |
1694 *x++ = '{'; | |
1695 /* Preserve the original case. */ | |
1696 qxestrncpy (x, o, s - o); | |
1697 x += s - o; | |
1698 *x++ = '}'; | |
1699 } | |
1700 else | |
1701 { | |
1702 /* Preserve the original case. */ | |
1703 qxestrncpy (x, o, s - o); | |
1704 x += s - o; | |
1705 } | |
1706 } | |
1668 } | 1707 } |
1669 | 1708 |
1670 *x = 0; | 1709 *x = 0; |
1671 | 1710 |
1672 /* If /~ or // appears, discard everything through first slash. */ | 1711 /* If /~ or // appears, discard everything through first slash. */ |
1687 && p > nm && IS_DIRECTORY_SEP (p[-1])) | 1726 && p > nm && IS_DIRECTORY_SEP (p[-1])) |
1688 xnm = p; | 1727 xnm = p; |
1689 #endif | 1728 #endif |
1690 | 1729 |
1691 return make_string (xnm, x - xnm); | 1730 return make_string (xnm, x - xnm); |
1692 | |
1693 badsubst: | |
1694 syntax_error ("Bad format environment-variable substitution", filename); | |
1695 missingclose: | |
1696 syntax_error ("Missing \"}\" in environment-variable substitution", | |
1697 filename); | |
1698 badvar: | |
1699 syntax_error_2 ("Substituting nonexistent environment variable", | |
1700 filename, build_intstring (target)); | |
1701 | |
1702 RETURN_NOT_REACHED (Qnil); | |
1703 } | 1731 } |
1704 | 1732 |
1705 /* A slightly faster and more convenient way to get | 1733 /* A slightly faster and more convenient way to get |
1706 (directory-file-name (expand-file-name FOO)). */ | 1734 (directory-file-name (expand-file-name FOO)). */ |
1707 | 1735 |