Unix file separator "/" is used explicitely in some file handling code of the SDK instead of a portable value such as QDir::separator()
About you
CamiTK developper
Overview
While reading code in libraries/core/viewer/RendererWidget.cpp I found a line of code which assumes that file path are using the unix separator '/'.
QString filePrefix = QFileInfo(filename).absolutePath() + "/" + QFileInfo(filename).baseName();
The same type of separator use is found at multiple places in the SDK:
$ grep -n --include "*.cpp" --include "*.h" '"/"' * -R
actions/application/file/SaveAsAction.cpp:178: QFileDialog saveFileDialog(nullptr, tr("Save File As..."), QFileInfo(compfileName).dir().canonicalPath() + "/" + suggestedName, test);
actions/application/file/SaveAsAction.cpp:183: QString filename = QFileDialog::getSaveFileName(nullptr, tr("Save File As..."), QFileInfo(compfileName).dir().canonicalPath() + "/" + suggestedName, test);
applications/actionstatemachine/SaveActionState.cpp:107: (*outIt)->setFileName(saveDirName + "/" + compName + ".mha");
applications/actionstatemachine/SaveActionState.cpp:109: (*compIt)->setFileName(compDir + "/" + compName + compExt);
applications/actionstatemachine/SaveActionState.cpp:114: (*logStream) << compDir + "/" + compName + compExt << "' type='" << compType << "'/>" << Qt::endl;
applications/testcomponents/main.cpp:190: comp->setFileName(outputDirectory + "/" + inputComponent.fileName());
applications/wizard/GeneratingCEPState.cpp:105: QString outputFileName = dir.absolutePath() + "/" + cepDirName + "/libraries/" + libraryName + "/" + shortFileName;
components/vtkimage/VtkImageComponentExtension.cpp:251: QString filePattern = fileInfo.absoluteDir().absolutePath() + "/" + fileInfo.baseName();
components/off/OffExtension.cpp:71: QString baseFilename = QFileInfo(component->getFileName()).absolutePath() + "/" + QFileInfo(component->getFileName()).completeBaseName();
components/obj/ObjExtension.cpp:68: QString baseFilename = QFileInfo(component->getFileName()).absolutePath() + "/" + QFileInfo(component->getFileName()).completeBaseName();
libraries/core/viewer/RendererWidget.cpp:572: QString filePrefix = QFileInfo(filename).absolutePath() + "/" + QFileInfo(filename).baseName();
libraries/core/utils/CamiTKLogger.cpp:158: QFile::rename(fileToMove.absoluteFilePath(), logFileDirectory.path() + "/" + logFileName);
libraries/core/utils/CamiTKLogger.cpp:162: logFile = new QFile(logFileDirectory.path() + "/" + logFileName);
libraries/core/ExtensionManager.cpp:322: QString privateLibToLoad = Core::getGlobalInstallDir() + "/" + QString(Core::libDir) + "/" + QString(Core::shortVersion) + "/" + libname.cap(1);
libraries/core/ExtensionManager.cpp:328: privateLibToLoad = Core::getGlobalInstallDir() + "/" + QString(Core::libDir) + "/" + QString(Core::shortVersion) + "/" + libname.cap(1);
libraries/core/ExtensionManager.cpp:367: // add one cdUp() for each "/" inside Core::libDir (to take into account any multiarch configuration that
libraries/core/ExtensionManager.cpp:576: appFilePath.replace("/", "\\");
libraries/core/ExtensionManager.cpp:717: if (potentialPath.cd(potentialLibDir + "/" + QString(Core::shortVersion))) {
libraries/core/Core.cpp:314: QStringList installDirectories = getInstallDirectories(QString(Core::libDir) + "/" + QString(Core::shortVersion) + "/" + extensionType);
libraries/core/Core.cpp:318: QStringList libInstallDirectories = getInstallDirectories("lib/" + QString(Core::shortVersion) + "/" + extensionType, false);
libraries/cepgenerator/CepGenerator.cpp:95: devDirectoryName = devDirectoryName + "/";
libraries/cepgenerator/ComponentExtensionGenerator.cpp:309: QString testFileName = currentDirectory.absolutePath() + "/" + "empty." + suffix;
Same with '/':
libraries/core/ExtensionManager.cpp:369: for (int i = 0; i < QString(Core::libDir).count(QLatin1Char('/')); i++) {
components/vtkmesh/VtkMeshUtil.cpp:230: size_t nbegin = vtkFileName.find_last_of('/');
Outside the SDK, tutorials and modeling also contain instances of the same problem:
modeling/libraries/mml/monitoring/MonitoringManager.cpp:565: if (mmlIn->simulatorFile().get()[0] != '/') {
modeling/libraries/mml/monitoring/AnsysSimulator.cpp:48: if (workingDir[workingDir.length() - 1] != '/') {
modeling/libraries/mml/monitoring/ArtiSynthSimulator.cpp:44: if (workingDir[workingDir.length() - 1] != '/') {
modeling/applications/pmltools/obj2pml/obj2pml.cpp:111: unsigned int slash = buff.find('/');
modeling/actions/mml/GenerateModel.cpp:86: QString baseFilename = QFileInfo(originalFilename).absolutePath() + "/" + QFileInfo(originalFilename).completeBaseName();
modeling/libraries/mml/monitoring/MonitoringManager.cpp:53: size_t slashPlace = mmlPath.find_last_of("/");
modeling/libraries/mml/monitoring/MonitoringManager.cpp:97: QString guessPMLFilename = QFileInfo(fi).absolutePath() + "/" + QFileInfo(fi).baseName() + ".pml";
modeling/libraries/mml/monitoring/SofaSimulator.cpp:80: QString scnFileName = mmlFileInfo.absolutePath() + "/" + mmlFileInfo.baseName() + ".scn";
modeling/libraries/mml/monitoring/SofaSimulator.cpp:88: scnFileName = QDir::tempPath() + "/" + mmlFileInfo.baseName() + ".scn";
modeling/libraries/mml/monitoring/SofaSimulator.cpp:92: QString mshFileName = QDir::tempPath() + "/" + QFileInfo(monitoringManager->getPmlFileName().c_str()).baseName() + ".msh";
modeling/libraries/mml/monitoring/SofaWidget.cpp:87: size_t slashPlace = scnFileTemp.find_last_of("/");
modeling/libraries/mml/monitoring/AnsysSimulator.cpp:49: workingDir = workingDir + "/";
modeling/libraries/mml/monitoring/ArtiSynthSimulator.cpp:45: workingDir = workingDir + "/";
modeling/libraries/mml/monitoring/Reference.cpp:82: size_t slashPlace = refpath.find_last_of("/");
modeling/components/mmlcomponent/MMLComponent.cpp:61: file = QDir::tempPath() + "/" + QFileInfo(fi).baseName() + ".mml";
modeling/applications/pmltools/extractCells/extractCells.cpp:147: extracted = new StructuralComponent(pm, c1 + "/" + c2 + " extracted");
modeling/applications/pmltools/extractCells/extractCells.cpp:172: cout << '\r' << (i + 1) << "/" << ok;
modeling/applications/pmltools/extractCells/extractCells.cpp:192: pm->setName(pm->getName() + " " + c1 + "/" + c2 + " Extracted");
tutorials/components/mixed/MixedComponent.cpp:41: QString mhaFile = QFileInfo(file).absolutePath() + "/" + filename.c_str();
tutorials/components/mixed/MixedComponent.cpp:43: QString vtkFile = QFileInfo(file).absolutePath() + "/" + filename.c_str();
tutorials/applications/fancy/FancyMainWindow.cpp:221: ui.slideValue->setText(QString("%1").arg((currentSliceId + 1), 3) + "/" + QString("%1").arg(maxSliceId, 3));
tutorials/applications/nogui/main.cpp:85: QString outputFileName = QDir::currentPath() + "/" + QFileInfo(image->getFileName()).completeBaseName() + "-output." + QFileInfo(image->getFileName()).suffix(
Actual VS Expected Result
As CamiTK is multiplaform, the code should not assume that the path separator is the '/' char. Using Qt Resources might be an exception to this, so each line of code should be checked manually before replacing '/' by QDir::separator().
Interpretation & Possible fixes
Replacing '/' char with QDir::separator() when building file paths.
CamiTK Version
CamiTK 5.1.dev.develop.f3f104d8
please do not remove anything below this line
Edited by Manik Bhattacharjee