From 1f6c0f63a72a506fdde92fe0b495cdcaea9c4f1e Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Fri, 7 Jun 2019 12:51:25 +0200 Subject: [PATCH] CMake: Implement cmake true/false semantics Implement proper support for cmakes true/false value semantics. Change-Id: I127f73f62d1b7b21b2fee032f40c9cc448b876b8 Reviewed-by: Alessandro Portale Reviewed-by: Tobias Hunger --- .../cmakeprojectmanager/cmakeconfigitem.cpp | 19 +++++++++++++++++++ .../cmakeprojectmanager/cmakeconfigitem.h | 3 +++ .../cmakeprojectmanager/configmodel.cpp | 13 ++++--------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp index c3e27c001b5..24e6c174709 100644 --- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.cpp @@ -148,6 +148,25 @@ CMakeConfigItem::Type CMakeConfigItem::typeStringToType(const QByteArray &type) return CMakeConfigItem::INTERNAL; } +Utils::optional CMakeConfigItem::toBool(const QByteArray &value) +{ + // Taken from CMakes if() documentation: + // "Named boolean constants are case-insensitive." + const QString v = QString::fromUtf8(value).toUpper(); + + bool isInt = false; + v.toInt(&isInt); + + // "False if the constant is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, the empty string, or ends in the suffix -NOTFOUND." + if (v == "0" || v == "OFF" || v == "NO" || v == "FALSE" || v == "N" || v == "IGNORE" || v == "NOTFOUND" || v == "" || v.endsWith("-NOTFOUND")) + return false; + // "True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number." + if (v == "1" || v == "ON" || v == "YES" || v == "TRUE" || v == "Y" || isInt) + return true; + + return {}; +} + QString CMakeConfigItem::expandedValue(const ProjectExplorer::Kit *k) const { return expandedValue(k->macroExpander()); diff --git a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h index 16bc8acea3c..67f4f5009a9 100644 --- a/src/plugins/cmakeprojectmanager/cmakeconfigitem.h +++ b/src/plugins/cmakeprojectmanager/cmakeconfigitem.h @@ -25,6 +25,8 @@ #pragma once +#include + #include #include @@ -50,6 +52,7 @@ public: const QList &input); static QStringList cmakeSplitValue(const QString &in, bool keepEmpty = false); static Type typeStringToType(const QByteArray &typeString); + static Utils::optional toBool(const QByteArray &value); bool isNull() const { return key.isEmpty(); } QString expandedValue(const ProjectExplorer::Kit *k) const; diff --git a/src/plugins/cmakeprojectmanager/configmodel.cpp b/src/plugins/cmakeprojectmanager/configmodel.cpp index 804dc6d7704..c402478d3c4 100644 --- a/src/plugins/cmakeprojectmanager/configmodel.cpp +++ b/src/plugins/cmakeprojectmanager/configmodel.cpp @@ -36,13 +36,6 @@ namespace CMakeProjectManager { -static bool isTrue(const QString &value) -{ - const QString lower = value.toLower(); - return lower == QStringLiteral("true") || lower == QStringLiteral("on") - || lower == QStringLiteral("1") || lower == QStringLiteral("yes"); -} - ConfigModel::ConfigModel(QObject *parent) : Utils::TreeModel<>(parent) { setHeader({tr("Key"), tr("Value")}); @@ -431,15 +424,17 @@ QVariant ConfigModelTreeItem::data(int column, int role) const } case 1: { const QString value = currentValue(); + const auto boolValue = CMakeConfigItem::toBool(value.toUtf8()); + const bool isTrue = boolValue.has_value() && boolValue.value(); switch (role) { case Qt::CheckStateRole: return (dataItem->type == ConfigModel::DataItem::BOOLEAN) - ? QVariant(isTrue(value) ? Qt::Checked : Qt::Unchecked) : QVariant(); + ? QVariant(isTrue ? Qt::Checked : Qt::Unchecked) : QVariant(); case Qt::DisplayRole: return value; case Qt::EditRole: - return (dataItem->type == ConfigModel::DataItem::BOOLEAN) ? QVariant(isTrue(value)) : QVariant(value); + return (dataItem->type == ConfigModel::DataItem::BOOLEAN) ? QVariant(isTrue) : QVariant(value); case Qt::FontRole: { QFont font; font.setBold((dataItem->isUserChanged || dataItem->isUserNew) && !dataItem->isUnset);