| 654 | | if (slash == -1) |
| 655 | | return QLatin1String("."); |
| 656 | | else if (!slash) |
| 657 | | return QLatin1String("/"); |
| 658 | | return d->filePath.left(slash); |
| 659 | | } else if (file == AbsoluteName || file == AbsolutePathName) { |
| | 668 | if(slash == -1) { |
| | 669 | if(d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) |
| | 670 | return d->filePath.left(2); |
| | 671 | return QString::fromLatin1("."); |
| | 672 | } else { |
| | 673 | if(!slash) |
| | 674 | return QString::fromLatin1("/"); |
| | 675 | if(slash == 2 && d->filePath.length() >= 2 && d->filePath.at(1) == QLatin1Char(':')) |
| | 676 | slash++; |
| | 677 | return d->filePath.left(slash); |
| | 678 | } |
| | 679 | } else if(file == AbsoluteName || file == AbsolutePathName) { |
| 661 | | if (d->filePath.isEmpty() || !d->filePath.startsWith(QLatin1Char('/'))) |
| 662 | | ret = QDir::currentPath(); |
| 663 | | if (!d->filePath.isEmpty() && d->filePath != QLatin1String(".")) { |
| 664 | | if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) |
| 665 | | ret += QLatin1Char('/'); |
| 666 | | ret += d->filePath; |
| 667 | | } |
| 668 | | if (ret == QLatin1String("/")) |
| 669 | | return ret; |
| 670 | | bool isDir = ret.endsWith(QLatin1Char('/')); |
| 671 | | ret = QDir::cleanPath(ret); |
| 672 | | if (isDir) |
| 673 | | ret += QLatin1String("/"); |
| | 681 | |
| | 682 | if (!isRelativePath()) { |
| | 683 | if (d->filePath.size() > 2 && d->filePath.at(1) == QLatin1Char(':') |
| | 684 | && d->filePath.at(2) != QLatin1Char('/') || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt |
| | 685 | d->filePath.startsWith(QLatin1Char('/')) // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt |
| | 686 | ) { |
| | 687 | char buf[PATH_MAX+1]; |
| | 688 | strcpy(buf, QFile::encodeName(d->filePath).constData()); |
| | 689 | _abspath(buf, buf, sizeof(buf)); |
| | 690 | ret = QFile::decodeName(buf); |
| | 691 | } else { |
| | 692 | ret = d->filePath; |
| | 693 | } |
| | 694 | } else { |
| | 695 | ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->filePath); |
| | 696 | } |
| | 697 | |
| | 698 | // The path should be absolute at this point. |
| | 699 | // From the docs : |
| | 700 | // Absolute paths begin with the directory separator "/" |
| | 701 | // (optionally preceded by a drive specification under Windows). |
| | 702 | if (ret.at(0) != QLatin1Char('/')) { |
| | 703 | Q_ASSERT(ret.length() >= 2); |
| | 704 | Q_ASSERT(ret.at(0).isLetter()); |
| | 705 | Q_ASSERT(ret.at(1) == QLatin1Char(':')); |
| | 706 | |
| | 707 | // Force uppercase drive letters. |
| | 708 | ret[0] = ret.at(0).toUpper(); |
| | 709 | } |
| | 710 | |
| 699 | | #if defined(__GLIBC__) && !defined(PATH_MAX) |
| 700 | | #define PATH_CHUNK_SIZE 256 |
| 701 | | char *s = 0; |
| 702 | | int len = -1; |
| 703 | | int size = PATH_CHUNK_SIZE; |
| 704 | | |
| 705 | | while (1) { |
| 706 | | s = (char *) ::realloc(s, size); |
| 707 | | if (s == 0) { |
| 708 | | len = -1; |
| 709 | | break; |
| | 737 | char buf[PATH_MAX+1]; |
| | 738 | int len = readlink(d->nativeFilePath.constData(), buf, PATH_MAX); |
| | 739 | if (len > 0) { |
| | 740 | buf[len] = '\0'; |
| | 741 | QString target = QDir::fromNativeSeparators(QFile::decodeName(QByteArray(buf))); |
| | 742 | QString ret; |
| | 743 | if (!::isRelativePath(target)) { |
| | 744 | if (target.size() > 2 && target.at(1) == QLatin1Char(':') |
| | 745 | && target.at(2) != QLatin1Char('/') || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt |
| | 746 | target.startsWith(QLatin1Char('/')) // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt |
| | 747 | ) { |
| | 748 | char buf[PATH_MAX+1]; |
| | 749 | strcpy(buf, QFile::encodeName(target).constData()); |
| | 750 | _abspath(buf, buf, sizeof(buf)); |
| | 751 | ret = QFile::decodeName(buf); |
| | 752 | } else { |
| | 753 | ret = target; |
| | 754 | } |
| | 755 | } else { |
| | 756 | if (S_ISDIR(d->st.st_mode)) { |
| | 757 | QDir parent(d->filePath); |
| | 758 | parent.cdUp(); |
| | 759 | ret = parent.path(); |
| | 760 | if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) |
| | 761 | ret += QLatin1Char('/'); |
| | 762 | } |
| | 763 | ret += target; |
| | 764 | |
| | 765 | if (::isRelativePath(ret)) { |
| | 766 | if (!isRelativePath()) { |
| | 767 | ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/'))) |
| | 768 | + QLatin1Char('/')); |
| | 769 | } else { |
| | 770 | ret.prepend(QDir::currentPath() + QLatin1Char('/')); |
| | 771 | } |
| | 772 | } |
| | 773 | ret = QDir::cleanPath(ret); |
| | 774 | if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) |
| | 775 | ret.chop(1); |
| 711 | | len = ::readlink(d->nativeFilePath.constData(), s, size); |
| 712 | | if (len < 0) { |
| 713 | | ::free(s); |
| 714 | | break; |
| | 777 | |
| | 778 | // The path should be absolute at this point. |
| | 779 | // From the docs : |
| | 780 | // Absolute paths begin with the directory separator "/" |
| | 781 | // (optionally preceded by a drive specification under Windows). |
| | 782 | if (ret.at(0) != QLatin1Char('/')) { |
| | 783 | Q_ASSERT(ret.length() >= 2); |
| | 784 | Q_ASSERT(ret.at(0).isLetter()); |
| | 785 | Q_ASSERT(ret.at(1) == QLatin1Char(':')); |
| | 786 | |
| | 787 | // Force uppercase drive letters. |
| | 788 | ret[0] = ret.at(0).toUpper(); |
| 716 | | if (len < size) { |
| 717 | | break; |
| 718 | | } |
| 719 | | size *= 2; |
| 720 | | } |
| 721 | | #else |
| 722 | | char s[PATH_MAX+1]; |
| 723 | | int len = readlink(d->nativeFilePath.constData(), s, PATH_MAX); |
| 724 | | #endif |
| 725 | | if (len > 0) { |
| 726 | | QString ret; |
| 727 | | if (S_ISDIR(d->st.st_mode) && s[0] != '/') { |
| 728 | | QDir parent(d->filePath); |
| 729 | | parent.cdUp(); |
| 730 | | ret = parent.path(); |
| 731 | | if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) |
| 732 | | ret += QLatin1Char('/'); |
| 733 | | } |
| 734 | | s[len] = '\0'; |
| 735 | | ret += QFile::decodeName(QByteArray(s)); |
| 736 | | #if defined(__GLIBC__) && !defined(PATH_MAX) |
| 737 | | ::free(s); |
| 738 | | #endif |
| 739 | | |
| 740 | | if (!ret.startsWith(QLatin1Char('/'))) { |
| 741 | | if (d->filePath.startsWith(QLatin1Char('/'))) { |
| 742 | | ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/'))) |
| 743 | | + QLatin1Char('/')); |
| 744 | | } else { |
| 745 | | ret.prepend(QDir::currentPath() + QLatin1Char('/')); |
| 746 | | } |
| 747 | | } |
| 748 | | ret = QDir::cleanPath(ret); |
| 749 | | if (ret.size() > 1 && ret.endsWith(QLatin1Char('/'))) |
| 750 | | ret.chop(1); |
| | 790 | |