[kdevelop] languages/plugins/custom-definesandincludes: Allow #define in .kdev_include_paths + fix crash due to 'auto'

David Nolden david.nolden.kde at art-master.de
Sun Jan 31 15:50:55 UTC 2016


Git commit fc45557c493842dcbd32a12f8aeb889967005646 by David Nolden.
Committed on 31/01/2016 at 15:50.
Pushed by zwabel into branch 'master'.

Allow #define in .kdev_include_paths + fix crash due to 'auto'

1. Always use custom include paths and #defines specified in
    .kdev_include_paths, even when we're in a project. If the user
    specifies it then it should be used, and not silently ignored.
2. Also allow specifying #define directives in .kdev_include_paths.
3. Fix a crash that happend when when invoking the custom include
   paths UI without a project open, not specifying any include paths,
   and pressing OK. The problem was the removeSettings function; it
   it uses the 'auto' type specifier for a QString that is based on
   an expression which concatenates a string reference with something.
   Apparently, the deduced type is a reference to a temporary QString,
   and the application crashes when trying to use the reference.
   Conclusion: Don't overuse the 'auto' keyword, it's not as safe
   as you think. Also it makes understanding the code harder, because
   you don't instantly see the type that's actually used.
CCMAIL: kdevelop-devel at kdevelop.org

M  +12   -3    languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp
M  +7    -4    languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectcustomincludepaths.ui
M  +19   -7    languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.cpp
M  +1    -1    languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.h

http://commits.kde.org/kdevelop/fc45557c493842dcbd32a12f8aeb889967005646

diff --git a/languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp b/languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp
index ad7d3e1..06c4db4 100644
--- a/languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp
+++ b/languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp
@@ -144,6 +144,8 @@ Defines DefinesAndIncludesManager::defines( ProjectBaseItem* item, Type type  )
         merge(&defines, findConfigForItem(m_settings->readPaths(cfg), item).defines);
     }
 
+    merge(&defines, m_noProjectIPM->includesAndDefines(item->path().path()).second);
+
     return defines;
 }
 
@@ -176,6 +178,8 @@ Path::List DefinesAndIncludesManager::includes( ProjectBaseItem* item, Type type
         }
     }
 
+    includes += m_noProjectIPM->includesAndDefines(item->path().path()).first;
+
     return includes;
 }
 
@@ -200,14 +204,17 @@ void DefinesAndIncludesManager::registerProvider(IDefinesAndIncludesManager::Pro
     m_providers.push_back(provider);
 }
 
-Defines DefinesAndIncludesManager::defines(const QString&) const
+Defines DefinesAndIncludesManager::defines(const QString& path) const
 {
-    return m_settings->provider()->defines(nullptr);
+    Defines ret = m_settings->provider()->defines(nullptr);
+    merge(&ret, m_noProjectIPM->includesAndDefines(path).second);
+    return ret;
 }
 
 Path::List DefinesAndIncludesManager::includes(const QString& path) const
 {
-    return m_settings->provider()->includes(nullptr) + m_noProjectIPM->includes(path);
+    return m_settings->provider()->includes(nullptr) 
+           + m_noProjectIPM->includesAndDefines(path).first;
 }
 
 void DefinesAndIncludesManager::openConfigurationDialog(const QString& pathToFile)
@@ -241,6 +248,8 @@ Defines DefinesAndIncludesManager::definesInBackground(const QString& path) cons
         }
     }
 
+    merge(&defines, m_noProjectIPM->includesAndDefines(path).second);
+
     return defines;
 }
 
diff --git a/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectcustomincludepaths.ui b/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectcustomincludepaths.ui
index e1fa50e..f14ba07 100644
--- a/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectcustomincludepaths.ui
+++ b/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectcustomincludepaths.ui
@@ -22,8 +22,7 @@
         <item>
          <widget class="KUrlRequester" name="storageDirectory">
           <property name="toolTip">
-           <string>The custom include-path will be stored in a special file called ".kdev_include_paths" stored within a source directory.
- The custom path will be used for all files below that directory.</string>
+           <string>The custom include-path will be stored in a special file called ".kdev_include_paths" stored within a source directory.</string>
           </property>
          </widget>
         </item>
@@ -35,13 +34,17 @@
    <item>
     <widget class="QGroupBox" name="groupBox">
      <property name="title">
-      <string>Custom include paths</string>
+      <string>Custom include paths or #define's</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
       <item row="0" column="0">
        <layout class="QHBoxLayout" name="horizontalLayout_2">
         <item>
-         <widget class="QPlainTextEdit" name="customIncludePaths"/>
+         <widget class="QPlainTextEdit" name="customIncludePaths">
+         <property name="toolTip">
+         <string>The plain list of include paths. You may also define custom macros here by adding "#define NAME VALUE" lines.</string>
+         </property>
+         </widget>
         </item>
         <item>
          <layout class="QVBoxLayout" name="verticalLayout">
diff --git a/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.cpp b/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.cpp
index 4c9c193..fb46102 100644
--- a/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.cpp
+++ b/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.cpp
@@ -41,7 +41,7 @@ const QString includePathsFile = ".kdev_include_paths";
 
 bool removeSettings(const QString& storageDirectory)
 {
-    auto file = storageDirectory + QDir::separator() + includePathsFile;
+    QString file = storageDirectory + QDir::separator() + includePathsFile;
     return QFile::remove(file);
 }
 
@@ -71,7 +71,8 @@ QString NoProjectIncludePathsManager::findConfigurationFile(const QString& path)
     return {};
 }
 
-Path::List NoProjectIncludePathsManager::includes(const QString& path)
+std::pair<Path::List, QHash<QString, QString>> 
+    NoProjectIncludePathsManager::includesAndDefines(const QString& path)
 {
     QFileInfo fi(path);
 
@@ -79,7 +80,8 @@ Path::List NoProjectIncludePathsManager::includes(const QString& path)
     if (pathToFile.isEmpty()) {
         return {};
     }
-    Path::List ret;
+    Path::List includes;
+    QHash<QString, QString> defines;
 
     QFile f(pathToFile);
     if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
@@ -87,18 +89,28 @@ Path::List NoProjectIncludePathsManager::includes(const QString& path)
         QFileInfo dir(pathToFile);
         for (const auto& line : lines) {
             auto textLine = line.trimmed();
+            if (textLine.startsWith("#define ")) {
+                QStringList items = textLine.split(' ');
+                if (items.length() > 1)
+                {
+                    defines[items[1]] = QStringList(items.mid(2)).join(' ');
+                }else{
+                    qWarning() << i18n("Bad #define directive in %1: %1", pathToFile, textLine);
+                }
+                continue;
+            }
             if (!textLine.isEmpty()) {
                 QFileInfo pathInfo(textLine);
                 if (pathInfo.isRelative()) {
-                    ret << Path(dir.canonicalPath() + QDir::separator() + textLine);
+                    includes << Path(dir.canonicalPath() + QDir::separator() + textLine);
                 } else {
-                    ret << Path(textLine);
+                    includes << Path(textLine);
                 }
             }
         }
         f.close();
     }
-    return ret;
+    return std::make_pair(includes, defines);
 }
 
 bool NoProjectIncludePathsManager::writeIncludePaths(const QString& storageDirectory, const QStringList& includePaths)
@@ -128,7 +140,7 @@ void NoProjectIncludePathsManager::openConfigurationDialog(const QString& path)
     auto dir = fi.absoluteDir().absolutePath();
     cip.setStorageDirectory(dir);
 
-    auto paths = includes(path);
+    auto paths = includesAndDefines(path).first;
 
     cip.setCustomIncludePaths(pathListToStringList(paths));
 
diff --git a/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.h b/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.h
index f426648..7a900ee 100644
--- a/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.h
+++ b/languages/plugins/custom-definesandincludes/noprojectincludesanddefines/noprojectincludepathsmanager.h
@@ -32,7 +32,7 @@ class NoProjectIncludePathsManager
 {
 public:
     /// @return list of include directories for @p oath
-    Path::List includes( const QString& path );
+    std::pair<Path::List, QHash<QString, QString>> includesAndDefines( const QString& path );
 
     /// Opens the configuration page for file with the @p path
     void openConfigurationDialog( const QString& path );


More information about the KDevelop-devel mailing list