Changeset 365 for trunk/src


Ignore:
Timestamp:
Nov 30, 2009, 11:51:23 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

corelib/io: Make sure QDir::absoluteFilePath() works correctly on OS/2 (this is the only bit left after rolling back r355 and friends).

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

Legend:

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

    r363 r365  
    732732{
    733733    Q_D(const QDir);
     734
     735#ifdef Q_OS_OS2
     736
     737    // On OS/2, paths like "A:bbb.txt" and "\ccc.dat" are not absolute (because
     738    // they may lead to different locations depending on where we are). This
     739    // requires special processing here. Don't be confused that everywhere else
     740    // in Qt (except QFSFileEngine::fileName() on OS/2) these paths will be
     741    // still considered absolute -- the latter is already so confusing and
     742    // inconsistent that we cannot make it any worse, while this function is
     743    // the only way to properly handle such paths w/o introducing custom
     744    // processing in each Qt application and we rely on it at least in
     745    // QLibraryInfo. See also isRelativePath() and isNotReallyAbsolutePath() in
     746    // qfsfileengine_os2.cpp.
     747
     748    QString fn = QDir::fromNativeSeparators(fileName);
     749    if (!d->data->fileEngine)
     750        return fn;
     751
     752    bool curDriveRelative = false;
     753    bool curDirOnDriveRelative = false;
     754    if (isAbsolutePath(fn)) {
     755        // filter out not really absolute cases
     756        QChar ch0, ch1, ch2;
     757        if (fn.length()) ch0 = fn.at(0);
     758        if (fn.length() > 1) ch1 = fn.at(1);
     759        if (fn.length() > 2) ch2 = fn.at(2);
     760        curDriveRelative = ch0 == QLatin1Char('/') && ch1 != QLatin1Char('/'); // "\ccc.dat"
     761        if (!curDriveRelative) {
     762            curDirOnDriveRelative = ch0.isLetter() && ch1 == QLatin1Char(':') && // "A:bbb.txt" (but not A:)
     763                                    !ch2.isNull() && ch2 != QLatin1Char('/');
     764            if (!curDirOnDriveRelative) {
     765                return fn; // really absolute ("A:\bla...", "\\server\share"), nothing to do
     766            }
     767        }
     768    }
     769
     770    QString ret = d->data->fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
     771
     772    if (!fn.isEmpty()) {
     773        if (curDirOnDriveRelative) {
     774            // QFileInfo::absoluteFilePath() knows what to do
     775            ret = QFileInfo(fn).absoluteFilePath();
     776        } else {
     777            if (curDriveRelative)
     778                ret = ret.left(2); // only take the drive name from this QDir
     779            else if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
     780                ret += QLatin1Char('/'); // append the missing slash
     781            ret += fn;
     782        }
     783    }
     784    return ret;
     785
     786#else // #ifdef Q_OS_OS2
     787
    734788    if (isAbsolutePath(fileName))
    735789        return fileName;
     
    753807    }
    754808    return ret;
     809
     810#endif // #ifdef Q_OS_OS2
    755811}
    756812
  • trunk/src/corelib/io/qfsfileengine_os2.cpp

    r363 r365  
    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, paths like "A:bbb.txt" and "\ccc.dat" are not absolute (because
     653    // they may lead to different locations depending on where we are). However,
     654    // fixing this function will break an unfixable amount of invalid code in Qt
     655    // and qmake (just search for isRelativePath in there) so that we have to
     656    // live with it... See also QDir::absoluteFilePath() and
     657    // isNotReallyAbsolutePath() below.
     658
     659    return !(path.startsWith(QLatin1Char('/')) || // "\ccc.dat" or "\\server\share..."
     660             (path.length() >= 2 && path.at(0).isLetter() && // "A:bbb..." or "A:\bbb..."
     661              path.at(1) == QLatin1Char(':')));
     662}
     663
     664static bool isNotReallyAbsolutePath(const QString &path)
     665{
     666    // see isRelativePath(). Intended to detect a false absolute case when
     667    // isRelativePath() returns true
     668
     669    QChar ch0, ch1, ch2;
     670    if (path.length()) ch0 = path.at(0);
     671    if (path.length() > 1) ch1 = path.at(1);
     672    if (path.length() > 2) ch2 = path.at(2);
     673    return ((ch0 == QLatin1Char('/') && ch1 != QLatin1Char('/')) || // "\ccc.dat"
     674            (ch0.isLetter() && ch1 == QLatin1Char(':') && // "A:bbb.txt" (but not A:)
     675             !ch2.isNull() && ch2 != QLatin1Char('/')));
    656676}
    657677
     
    687707        QString ret;
    688708
    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                 ) {
     709        if (!::isRelativePath(d->filePath)) {
     710            if (::isNotReallyAbsolutePath(d->filePath)) {
    694711                char buf[PATH_MAX+1];
    695712                strcpy(buf, QFile::encodeName(d->filePath).constData());
     
    749766                QString ret;
    750767                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                         ) {
     768                    if (::isNotReallyAbsolutePath(target)) {
    755769                        char buf[PATH_MAX+1];
    756770                        strcpy(buf, QFile::encodeName(target).constData());
Note: See TracChangeset for help on using the changeset viewer.