Changeset 355 for trunk


Ignore:
Timestamp:
Nov 28, 2009, 5:20:07 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

corelib/io: On OS/2, treat "A:bbb.txt" and "/ccc.dat" as relative paths not as absolute (the absolute path, by definition, leads to the same object from any location which is not true for these paths).

Location:
trunk/src/corelib/io
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/corelib/io/qdir.cpp

    r172 r355  
    732732{
    733733    Q_D(const QDir);
     734
     735
     736
     737
     738
     739
     740
     741
     742
     743
     744
     745
     746
     747
     748
     749
     750
     751
     752
     753
     754
     755
     756
     757
     758
     759
     760
     761
     762
     763
     764
     765
     766
     767
     768
     769
     770
     771
     772
     773
     774
     775
     776
     777
     778
    734779    if (isAbsolutePath(fileName))
    735780        return fileName;
     
    753798    }
    754799    return ret;
     800
     801
    755802}
    756803
  • trunk/src/corelib/io/qfileinfo.cpp

    r172 r355  
    586586    drive letter, except for network shares that are not mapped to a
    587587    drive letter, in which case the path will begin '//sharename/'.
    588     QFileInfo will uppercase drive letters. Note that QDir does not do
    589     this. The code snippet below shows this.
     588    QFileInfo will uppercase drive letters. Note that QDir does not
     589    this. The code snippet below shows this.
    590590
    591591    \snippet doc/src/snippets/code/src_corelib_io_qfileinfo.cpp newstuff
  • trunk/src/corelib/io/qfsfileengine_os2.cpp

    r177 r355  
    650650static bool isRelativePath(const QString &path)
    651651{
    652     return !(path.startsWith(QLatin1Char('/'))
    653         || (path.length() >= 2
    654         && ((path.at(0).isLetter() && path.at(1) == QLatin1Char(':'))
    655         || (path.at(0) == QLatin1Char('/') && path.at(1) == QLatin1Char('/')))));                // drive, e.g. a:
     652        // On OS/2, "A:bbb.txt" and "/ccc.dat" are relative paths
     653    return !(path.startsWith(QLatin1String("//")) ||
     654             (path.length() >= 2 && path.at(0).isLetter() &&
     655              path.at(1) == QLatin1Char(':') &&
     656              // we treat "D:" as absolute while "D:aaa" as relative
     657              (path.length() == 2 || path.at(2) == QLatin1Char('/'))));
    656658}
    657659
     
    686688    } else if(file == AbsoluteName || file == AbsolutePathName) {
    687689        QString ret;
    688 
    689         if (!isRelativePath()) {
    690             if (d->filePath.size() > 2 && d->filePath.at(1) == QLatin1Char(':')
    691                 && d->filePath.at(2) != QLatin1Char('/') || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt
    692                 d->filePath.startsWith(QLatin1Char('/'))    // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt
    693                 ) {
     690        if (isRelativePath()) {
     691            if ((d->filePath.size() > 2 && d->filePath.at(1) == QLatin1Char(':') &&
     692                 d->filePath.at(2) != QLatin1Char('/')) ||    // path relative to the current dir of the given drive, so Z:a.txt -> Z:\currentpath\a.txt
     693                (d->filePath.startsWith(QLatin1Char('/')))) { // path relative to the root of the current drive, so \a.txt -> Z:\a.txt
    694694                char buf[PATH_MAX+1];
    695695                strcpy(buf, QFile::encodeName(d->filePath).constData());
    696696                _abspath(buf, buf, sizeof(buf));
    697                 ret = QFile::decodeName(buf);
     697                ret = QDir::cleanPath(QFile::decodeName(buf));
     698                if (::isRelativePath(ret)) {
     699                    // still relative, this means we have "Z:aaa" but there is no such drive Z:
     700                    // just assume root is the current dir on Z:
     701                    Q_ASSERT(ret.at(1) == QLatin1Char(':'));
     702                    ret.insert(2, QLatin1Char('/'));
     703                }
    698704            } else {
    699                 ret = d->filePath;
     705                ret = ;
    700706            }
    701707        } else {
    702             ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + d->filePath);
     708            ret = ;
    703709        }
    704710
    705711        // The path should be absolute at this point.
    706         // From the docs :
    707         // Absolute paths begin with the directory separator "/"
    708         // (optionally preceded by a drive specification under Windows).
    709         if (ret.at(0) != QLatin1Char('/')) {
     712        // On OS/2, the absolute path always contains a "X:/" at the begining
     713        // where X is the drive letter, or "//" if it's a network share
     714        if (!ret.startsWith("//")) {
    710715            Q_ASSERT(ret.length() >= 2);
    711716            Q_ASSERT(ret.at(0).isLetter());
    712717            Q_ASSERT(ret.at(1) == QLatin1Char(':'));
     718
     719
     720
     721
     722
     723
    713724
    714725            // Force uppercase drive letters.
     
    718729        if (file == AbsolutePathName) {
    719730            int slash = ret.lastIndexOf(QLatin1Char('/'));
    720             if (slash < 0)
    721                 return ret;
    722             else if (ret.at(0) != QLatin1Char('/') && slash == 2)
    723                 return ret.left(3);      // include the slash
    724             else
    725                 return ret.left(slash > 0 ? slash : 1);
     731            if (!ret.startsWith("//")) {
     732                Q_ASSERT(slash >= 2);
     733                if (slash == 2)
     734                    ret = ret.left(3);  // include the slash if it's "X:/"
     735                else
     736                    ret = ret.left(slash);
     737            } else {
     738                Q_ASSERT(slash >= 1);
     739                if (slash == 1)
     740                    ret = ret.left(3);  // include the slash if it's "//"
     741                else
     742                    ret = ret.left(slash);
     743            }
    726744        }
    727745        return ret;
     
    733751        if (!ret.isEmpty() && file == CanonicalPathName) {
    734752            int slash = ret.lastIndexOf(QLatin1Char('/'));
    735             if (slash == -1)
    736                 ret = QDir::currentPath();
    737             else if (slash == 0)
    738                 ret = QLatin1String("/");
    739             ret = ret.left(slash);
     753            if (!ret.startsWith("//")) {
     754                Q_ASSERT(slash >= 2);
     755                if (slash == 2)
     756                    ret = ret.left(3);  // include the slash if it's "X:/"
     757                else
     758                    ret = ret.left(slash);
     759            } else {
     760                Q_ASSERT(slash >= 1);
     761                if (slash == 1)
     762                    ret = ret.left(3);  // include the slash if it's "//"
     763                else
     764                    ret = ret.left(slash);
     765            }
    740766        }
    741767        return ret;
     
    748774                QString target = QDir::fromNativeSeparators(QFile::decodeName(QByteArray(buf)));
    749775                QString ret;
    750                 if (!::isRelativePath(target)) {
    751                     if (target.size() > 2 && target.at(1) == QLatin1Char(':')
    752                         && target.at(2) != QLatin1Char('/') || // It's a drive-relative path, so Z:a.txt -> Z:\currentpath\a.txt
    753                         target.startsWith(QLatin1Char('/'))    // It's a absolute path to the current drive, so \a.txt -> Z:\a.txt
    754                         ) {
     776                if (::isRelativePath(target)) {
     777                    if ((target.size() > 2 && target.at(1) == QLatin1Char(':') &&
     778                         target.at(2) != QLatin1Char('/')) ||    // path relative to the current dir of the given drive, so Z:a.txt -> Z:\currentpath\a.txt
     779                        (target.startsWith(QLatin1Char('/')))) { // path relative to the root of the current drive, so \a.txt -> Z:\a.txt
    755780                        char buf[PATH_MAX+1];
    756781                        strcpy(buf, QFile::encodeName(target).constData());
    757782                        _abspath(buf, buf, sizeof(buf));
    758                         ret = QFile::decodeName(buf);
     783                        ret = QDir::cleanPath(QFile::decodeName(buf));
     784                        if (::isRelativePath(ret)) {
     785                            // still relative, this means we have "Z:aaa" but there is no such drive Z:
     786                            // just assume root is the current dir on Z:
     787                            Q_ASSERT(ret.at(1) == QLatin1Char(':'));
     788                            ret.insert(2, QLatin1Char('/'));
     789                        }
    759790                    } else {
    760                         ret = target;
     791                        if (S_ISDIR(d->st.st_mode)) {
     792                            QDir parent(d->filePath);
     793                            parent.cdUp();
     794                            ret = parent.path();
     795                            if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
     796                                ret += QLatin1Char('/');
     797                        }
     798                        ret += target;
     799
     800                        if (::isRelativePath(ret)) {
     801                            if (!isRelativePath()) {
     802                                ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/')))
     803                                            + QLatin1Char('/'));
     804                            } else {
     805                                ret.prepend(QDir::currentPath() + QLatin1Char('/'));
     806                            }
     807                        }
     808                        ret = QDir::cleanPath(ret);
     809                        if (ret.size() > 1 && ret.endsWith(QLatin1Char('/')))
     810                            ret.chop(1);
    761811                    }
    762812                } else {
    763                     if (S_ISDIR(d->st.st_mode)) {
    764                         QDir parent(d->filePath);
    765                         parent.cdUp();
    766                         ret = parent.path();
    767                         if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
    768                             ret += QLatin1Char('/');
    769                     }
    770                     ret += target;
    771 
    772                     if (::isRelativePath(ret)) {
    773                         if (!isRelativePath()) {
    774                             ret.prepend(d->filePath.left(d->filePath.lastIndexOf(QLatin1Char('/')))
    775                                         + QLatin1Char('/'));
    776                         } else {
    777                             ret.prepend(QDir::currentPath() + QLatin1Char('/'));
    778                         }
    779                     }
    780                     ret = QDir::cleanPath(ret);
    781                     if (ret.size() > 1 && ret.endsWith(QLatin1Char('/')))
    782                         ret.chop(1);
     813                    ret = target;
    783814                }
    784815
     816
    785817                // The path should be absolute at this point.
    786                 // From the docs :
    787                 // Absolute paths begin with the directory separator "/"
    788                 // (optionally preceded by a drive specification under Windows).
    789                 if (ret.at(0) != QLatin1Char('/')) {
     818                // On OS/2, the absolute path always contains a "X:/" at the begining
     819                // where X is the drive letter, or "//" if it's a network share
     820                if (!ret.startsWith("//")) {
    790821                    Q_ASSERT(ret.length() >= 2);
    791822                    Q_ASSERT(ret.at(0).isLetter());
    792823                    Q_ASSERT(ret.at(1) == QLatin1Char(':'));
     824
     825
     826
     827
     828
     829
    793830
    794831                    // Force uppercase drive letters.
Note: See TracChangeset for help on using the changeset viewer.