'lightweight' QDir::isAbsolutePath replacement ?

Ralf Habacker ralf.habacker at freenet.de
Fri Mar 14 13:56:16 GMT 2008


Thiago Macieira schrieb:
> On Friday 14 March 2008 11:33:53 Ralf Habacker wrote:
>   
>> Thiago Macieira schrieb:
>>     
>>> On Friday 14 March 2008 10:35:12 Ralf Habacker wrote:
>>>       
>>>> Thiago Macieira schrieb:
>>>>         
>>>>> Ralf Habacker wrote:
>>>>>           
>>>>>>> Here's the patch it will appear in tonight's snapshot. It can't be as
>>>>>>> fast as Ralf's original code because there's at least one file engine
>>>>>>> that is queried first (the resource file engine).
>>>>>>>               
>>>>>> Thanks for your efforts.
>>>>>>             
>>>>> Patch reverted because it broke all our Windows builds.
>>>>>
>>>>> I do not have more time to dedicate for this before 4.4.0 final.
>>>>>           
>>>> I would take some time to make it complete but how to validate the patch
>>>> when the test app is not public available ?
>>>>         
>>> You can start by cleaning up your build and recompiling qmake and
>>> src/tools (moc, uic, rcc). That's where it broke.
>>>       
>> I took the snapshot qt-all-opensource-src-4.4.0-snapshot-20080314 and
>> tried to build it with msvc 2005 express version - moc, uic and rcc does
>> not have any build problems.
>>     
>
> This is the email I got from our developer:
>
> =====
> I've reverted the patch 301646, since it broke all Windows machines, 
> even win32-g++.
>
> qmake in release would crash violently, and debug build wouldn't 
> output anyhing, since it would spin forever on a certain file, making 
> the application crash due to no more stack space.
> =====
>   
The problems is that the new implementation does not return the same 
result as the old implementation.
I replaced QDir::isRelativePath by the following code

bool QDir::isRelativePath(const QString &path)
{
    bool a = QFileInfo(path).isRelative();
    bool b = QFileInfo::isRelative(path);
    if (a != b)
        qDebug() << path << a << b;
    return a;
}

and got when running qmake:

"\include\qtmain\headers.pri" false true
"\include\QtCore\headers.pri" false true
"\src\corelib\arch\arch.pri" false true
"\include\QtXml\headers.pri" false true
"\include\QtNetwork\headers.pri" false true
"\include\QtGui\headers.pri" false true
"\include\QtSql\headers.pri" false true
"\include\QtScript\headers.pri" false true
"\include\QtTest\headers.pri" false true
"\include\Qt3Support\headers.pri" false true
"\include\QtOpenGL\headers.pri" false true
"\include\QtXmlPatterns\headers.pri" false true
"\include\QtSvg\headers.pri" false true

it looks that the new implementation seems to assume that a path 
starting with '\' is a relative path. 

I have fixed this using the following implementation

bool QFSFileEngine::isRelativePath(const QString &path)
{
    if (path.size() == 0)
        return true;
#ifdef Q_OS_WIN
    return !(path.startsWith(QLatin1Char('/'))
           || path.startsWith(QLatin1Char('\\'))
           || (path.length() >= 2 &&
            ( (path.at(0).isLetter() && path.at(1) == QLatin1Char(':')))));
#else
    return path[0] != QLatin1Char('/');
#endif
}


Relating to your comment
+    // ### This code looks wrong
+    // "a:" and "c:foo" are relative, aren't they?

may be the following implementing help to avoid this

bool QFSFileEngine::isRelativePath(const QString &path)
{
    if (path.size() == 0)
        return true;
#ifdef Q_OS_WIN
    return !(path.startsWith(QLatin1Char('/'))
           || path.startsWith(QLatin1Char('\\'))
           || (path.length() >= 3 &&
            ( (path.at(0).isLetter() && path.at(1) == QLatin1Char(':')
                && (path.at(2) == QLatin1Char('/') || path.at(2) == 
QLatin1Char('\\')) )
            )));
#else
    return path[0] != QLatin1Char('/');
#endif
}

PS: It is not possible for me to provide a git based patch.  If wished I 
can provide a patch based on the above mentioned snapshot.

Ralf






More information about the kde-core-devel mailing list