summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CTest/cmCTestRunTest.cxx7
-rw-r--r--Source/QtDialog/CMakeLists.txt115
-rw-r--r--Source/QtDialog/CMakeSetup.cxx4
-rw-r--r--Source/QtDialog/EnvironmentDialog.cxx4
-rw-r--r--Source/QtDialog/QCMakeCacheView.cxx4
-rw-r--r--Source/QtDialog/QCMakeWidgets.cxx38
-rw-r--r--Source/cmCTest.cxx2
-rw-r--r--Source/cmCommandLineArgument.h159
-rw-r--r--Source/cmExportFileGenerator.cxx2
-rw-r--r--Source/cmMakefileTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaTargetGenerator.cxx2
-rw-r--r--Source/cmTarget.cxx1
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx9
-rw-r--r--Source/cmake.cxx125
-rw-r--r--Source/cmakemain.cxx418
16 files changed, 559 insertions, 335 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 4598fe4..1e9bbaa 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 19)
-set(CMake_VERSION_PATCH 20210106)
+set(CMake_VERSION_PATCH 20210107)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 4ba0ae1..5a6c775 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -139,7 +139,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode;
}
this->TestResult.CompletionStatus = s.str();
- cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped ");
+ outputStream << "***Skipped ";
skipped = true;
} else if (success != this->TestProperties->WillFail) {
this->TestResult.Status = cmCTestTestHandler::COMPLETED;
@@ -195,8 +195,9 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
sprintf(buf, "%6.2f sec", this->TestProcess->GetTotalTime().count());
outputStream << buf << "\n";
+ bool passedOrSkipped = passed || skipped;
if (this->CTest->GetTestProgressOutput()) {
- if (!passed) {
+ if (!passedOrSkipped) {
// If the test did not pass, reprint test name and error
std::string output = this->GetTestPrefix(completed, total);
std::string testName = this->TestProperties->Name;
@@ -216,7 +217,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName);
}
}
- if (!this->CTest->GetTestProgressOutput() || !passed) {
+ if (!this->CTest->GetTestProgressOutput() || !passedOrSkipped) {
cmCTestLog(this->CTest, HANDLER_OUTPUT, outputStream.str());
}
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 452a303..1d3c66e 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -3,20 +3,52 @@
project(QtDialog)
CMake_OPTIONAL_COMPONENT(cmake-gui)
-find_package(Qt5Widgets REQUIRED)
+set (QT_COMPONENTS
+ Core
+ Widgets
+ Gui
+)
+
+set(CMake_QT_MAJOR_VERSION "A" CACHE
+ STRING "Expected Qt major version. Valid values are A (auto-select), 5, 6.")
+set(SUPPORTED_QT_VERSIONS "A" 5 6)
+set_property(CACHE CMake_QT_MAJOR_VERSION PROPERTY STRINGS ${SUPPORTED_QT_VERSIONS})
+if(NOT CMake_QT_MAJOR_VERSION VERSION_EQUAL "A")
+ if(NOT CMake_QT_MAJOR_VERSION IN_LIST SUPPORTED_QT_VERSIONS)
+ message(FATAL_ERROR "Supported Qt versions are \"${SUPPORTED_QT_VERSIONS}\"."
+ " But CMake_QT_MAJOR_VERSION is set to ${CMake_QT_MAJOR_VERSION}.")
+ endif()
+ set(INSTALLED_QT_VERSION ${CMake_QT_MAJOR_VERSION})
+else()
+ find_package(Qt6Widgets QUIET)
+ set(INSTALLED_QT_VERSION 6)
+ if(NOT Qt6Widgets_FOUND)
+ find_package(Qt5Widgets QUIET)
+ if(NOT Qt5Widgets_FOUND)
+ message(FATAL_ERROR "Could not find a valid Qt installation.")
+ endif()
+ set(INSTALLED_QT_VERSION 5)
+ endif()
+endif()
+
+find_package(Qt${INSTALLED_QT_VERSION}
+ COMPONENTS ${QT_COMPONENTS}
+ REQUIRED QUIET
+)
set(CMake_QT_EXTRA_LIBRARIES)
# Try to find the package WinExtras for the task bar progress
if(WIN32)
- find_package(Qt5WinExtras QUIET)
- if (Qt5WinExtras_FOUND)
+ find_package(Qt${INSTALLED_QT_VERSION}WinExtras QUIET)
+ if (Qt${INSTALLED_QT_VERSION}WinExtras_FOUND)
add_definitions(-DQT_WINEXTRAS)
- list(APPEND CMake_QT_EXTRA_LIBRARIES Qt5::WinExtras)
+ list(APPEND CMake_QT_EXTRA_LIBRARIES Qt${INSTALLED_QT_VERSION}::WinExtras)
+ list(APPEND QT_COMPONENTS WinExtras)
endif()
endif()
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt${INSTALLED_QT_VERSION}Widgets_EXECUTABLE_COMPILE_FLAGS}")
if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES)
list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES})
@@ -34,8 +66,24 @@ endif()
# FIXME: This should be part of Qt5 CMake scripts, but unfortunately
# Qt5 support is missing there.
if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
- macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var)
- get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+ function(_qt_get_plugin_name_with_version target out_var)
+ string(REGEX REPLACE "^Qt::(.+)" "Qt${INSTALLED_QT_VERSION}::\\1"
+ qt_plugin_with_version "${target}")
+ if(TARGET "${qt_plugin_with_version}")
+ set("${out_var}" "${qt_plugin_with_version}" PARENT_SCOPE)
+ else()
+ set("${out_var}" "" PARENT_SCOPE)
+ endif()
+ endfunction()
+ macro(install_qt_plugin _qt_plugin_name _qt_plugins_var)
+ if(TARGET "${_qt_plugin_name}")
+ get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION)
+ else()
+ _qt_get_plugin_name_with_version("Qt::${_qt_plugin_name}" _qt_plugin_with_version_name)
+ if(TARGET "${_qt_plugin_with_version_name}")
+ get_target_property(_qt_plugin_path "${_qt_plugin_with_version_name}" LOCATION)
+ endif()
+ endif()
if(EXISTS "${_qt_plugin_path}")
get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME)
get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
@@ -51,19 +99,33 @@ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
${COMPONENT})
set(${_qt_plugins_var}
"${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}")
- else()
- message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
endif()
endmacro()
+ macro(install_qt_plugins _comps _plugins_var)
+ foreach(_qt_comp ${${_comps}})
+ if (INSTALLED_QT_VERSION VERSION_LESS 6)
+ set(_qt_module_plugins ${Qt${INSTALLED_QT_VERSION}${_qt_comp}_PLUGINS})
+ else()
+ get_target_property(_qt_module_plugins Qt${INSTALLED_QT_VERSION}::${_qt_comp} QT_PLUGINS)
+ endif()
+ foreach(_qt_plugin ${_qt_module_plugins})
+ if (INSTALLED_QT_VERSION VERSION_GREATER_EQUAL 6)
+ # Qt6 provides the plugins as individual packages that need to be found.
+ find_package(Qt${INSTALLED_QT_VERSION}${_qt_plugin} QUIET
+ PATHS ${Qt${INSTALLED_QT_VERSION}${_qt_comp}_DIR})
+ endif()
+ install_qt_plugin(${_qt_plugin} _plugins_var)
+ endforeach()
+ endforeach()
+ endmacro()
+ install_qt_plugins(QT_COMPONENTS QT_PLUGINS)
if(APPLE)
- install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
"[Paths]\nPlugins = ${_qt_plugin_dir}\n")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources"
${COMPONENT})
elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES)
- install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
"[Paths]\nPlugins = ../${_qt_plugin_dir}\n")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf"
@@ -72,8 +134,8 @@ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32))
endif()
endif()
-get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION)
-get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH)
+get_property(_Qt_Core_LOCATION TARGET Qt${INSTALLED_QT_VERSION}::Core PROPERTY LOCATION)
+get_filename_component(Qt_BIN_DIR "${_Qt_Core_LOCATION}" PATH)
if(APPLE)
get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH)
endif()
@@ -105,7 +167,7 @@ set(SRCS
WarningMessagesDialog.cxx
WarningMessagesDialog.h
)
-qt5_wrap_ui(UI_SRCS
+set(UI_SRCS
CMakeSetupDialog.ui
Compilers.ui
CrossCompiler.ui
@@ -114,7 +176,7 @@ qt5_wrap_ui(UI_SRCS
RegexExplorer.ui
WarningMessagesDialog.ui
)
-qt5_wrap_cpp(MOC_SRCS
+set(MOC_SRCS
AddCacheEntry.h
Compilers.h
CMakeSetupDialog.h
@@ -128,7 +190,17 @@ qt5_wrap_cpp(MOC_SRCS
RegexExplorer.h
WarningMessagesDialog.h
)
-qt5_add_resources(RC_SRCS CMakeSetup.qrc)
+set(QRC_SRCS CMakeSetup.qrc)
+
+if (INSTALLED_QT_VERSION VERSION_LESS 6)
+ qt5_wrap_ui(UI_BUILT_SRCS ${UI_SRCS})
+ qt5_wrap_cpp(MOC_BUILT_SRCS ${MOC_SRCS})
+ qt5_add_resources(QRC_BUILT_SRCS ${QRC_SRCS})
+else()
+ qt_wrap_ui(UI_BUILT_SRCS ${UI_SRCS})
+ qt_wrap_cpp(MOC_BUILT_SRCS ${MOC_SRCS})
+ qt_add_resources(QRC_BUILT_SRCS ${QRC_SRCS})
+endif()
if (FALSE) # CMake's bootstrap binary does not support automoc
set(CMAKE_AUTOMOC 1)
@@ -136,9 +208,9 @@ if (FALSE) # CMake's bootstrap binary does not support automoc
set(CMAKE_AUTOUIC 1)
else ()
list(APPEND SRCS
- ${UI_SRCS}
- ${MOC_SRCS}
- ${RC_SRCS})
+ ${UI_BUILT_SRCS}
+ ${MOC_BUILT_SRCS}
+ ${QRC_BUILT_SRCS})
endif ()
if(USE_LGPL)
@@ -153,13 +225,14 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(CMakeGUILib STATIC ${SRCS})
# CMake_QT_EXTRA_LIBRARIES have to come before the main libraries on the link line
-target_link_libraries(CMakeGUILib PUBLIC CMakeLib ${CMake_QT_EXTRA_LIBRARIES} Qt5::Core Qt5::Widgets)
+target_link_libraries(CMakeGUILib PUBLIC CMakeLib ${CMake_QT_EXTRA_LIBRARIES}
+ Qt${INSTALLED_QT_VERSION}::Core Qt${INSTALLED_QT_VERSION}::Widgets)
add_library(CMakeGUIMainLib STATIC CMakeSetup.cxx)
target_link_libraries(CMakeGUIMainLib PUBLIC CMakeGUILib)
add_executable(cmake-gui WIN32 MACOSX_BUNDLE CMakeGUIExec.cxx ${MANIFEST_FILE})
-target_link_libraries(cmake-gui CMakeGUIMainLib Qt5::Core)
+target_link_libraries(cmake-gui CMakeGUIMainLib Qt${INSTALLED_QT_VERSION}::Core)
if(WIN32)
target_sources(CMakeGUIMainLib INTERFACE $<TARGET_OBJECTS:CMakeVersion> CMakeSetup.rc)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 861c6e3..5debdb8 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -7,7 +7,6 @@
#include <QDir>
#include <QLocale>
#include <QString>
-#include <QTextCodec>
#include <QTranslator>
#include <QtPlugin>
@@ -122,9 +121,6 @@ int main(int argc, char** argv)
setlocale(LC_NUMERIC, "C");
- QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8");
- QTextCodec::setCodecForLocale(utf8_codec);
-
// tell the cmake library where cmake is
QDir cmExecDir(QApplication::applicationDirPath());
#if defined(Q_OS_MAC)
diff --git a/Source/QtDialog/EnvironmentDialog.cxx b/Source/QtDialog/EnvironmentDialog.cxx
index 846456c..d4f978c 100644
--- a/Source/QtDialog/EnvironmentDialog.cxx
+++ b/Source/QtDialog/EnvironmentDialog.cxx
@@ -81,7 +81,11 @@ bool EnvironmentSearchFilter::filterAcceptsRow(int row,
auto* model = this->sourceModel();
auto key =
model->data(model->index(row, 0, parent), Qt::DisplayRole).toString();
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
+ return key.contains(this->filterRegularExpression());
+#else
return key.contains(this->filterRegExp());
+#endif
}
EnvironmentDialog::EnvironmentDialog(const QProcessEnvironment& environment,
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index 22f5be1..7c9032e 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -47,7 +47,11 @@ protected:
// check all strings for a match
foreach (QString const& str, strs) {
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
+ if (str.contains(this->filterRegularExpression())) {
+#else
if (str.contains(this->filterRegExp())) {
+#endif
return true;
}
}
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
index e68faba..ca65d13 100644
--- a/Source/QtDialog/QCMakeWidgets.cxx
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -1,20 +1,23 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-// FIXME: Port to QFileSystemModel from the deprecated QDirModel.
-// Be sure completion works when incrementally editing existing paths.
#define QT_DEPRECATED_WARNINGS_SINCE QT_VERSION_CHECK(5, 14, 0)
#include "QCMakeWidgets.h"
#include <utility>
-#include <QDirModel>
#include <QFileDialog>
#include <QFileInfo>
#include <QResizeEvent>
#include <QToolButton>
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+# include <QFileSystemModel>
+#else
+# include <QDirModel>
+#endif
+
QCMakeFileEditor::QCMakeFileEditor(QWidget* p, QString var)
: QLineEdit(p)
, Variable(std::move(var))
@@ -93,8 +96,30 @@ void QCMakePathEditor::chooseFile()
}
}
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+// use same QFileSystemModel for all completers
+static QFileSystemModel* fileDirModel()
+
+{
+ static QFileSystemModel* m = nullptr;
+ if (!m) {
+ m = new QFileSystemModel();
+ }
+ return m;
+}
+static QFileSystemModel* pathDirModel()
+{
+ static QFileSystemModel* m = nullptr;
+ if (!m) {
+ m = new QFileSystemModel();
+ m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot);
+ }
+ return m;
+}
+#else
// use same QDirModel for all completers
static QDirModel* fileDirModel()
+
{
static QDirModel* m = nullptr;
if (!m) {
@@ -111,12 +136,19 @@ static QDirModel* pathDirModel()
}
return m;
}
+#endif
QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs)
: QCompleter(o)
{
+#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
+ QFileSystemModel* m = dirs ? pathDirModel() : fileDirModel();
+ this->setModel(m);
+ m->setRootPath(QString());
+#else
QDirModel* m = dirs ? pathDirModel() : fileDirModel();
this->setModel(m);
+#endif
}
QString QCMakeFileCompleter::pathFromIndex(const QModelIndex& idx) const
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 6507f38..6c1071d 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -2901,7 +2901,7 @@ bool cmCTest::GetFailover() const
bool cmCTest::GetTestProgressOutput() const
{
- return this->Impl->TestProgressOutput;
+ return this->Impl->TestProgressOutput && !GetExtraVerbose();
}
bool cmCTest::GetVerbose() const
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h
new file mode 100644
index 0000000..cbedf0a
--- /dev/null
+++ b/Source/cmCommandLineArgument.h
@@ -0,0 +1,159 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+template <typename FunctionSignature>
+struct cmCommandLineArgument
+{
+ enum class Values
+ {
+ Zero,
+ One,
+ Two,
+ ZeroOrOne,
+ OneOrMore
+ };
+
+ std::string InvalidSyntaxMessage;
+ std::string InvalidValueMessage;
+ std::string Name;
+ Values Type;
+ std::function<FunctionSignature> StoreCall;
+
+ template <typename FunctionType>
+ cmCommandLineArgument(std::string n, Values t, FunctionType&& func)
+ : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n))
+ , InvalidValueMessage(cmStrCat("Invalid value used with ", n))
+ , Name(std::move(n))
+ , Type(t)
+ , StoreCall(std::forward<FunctionType>(func))
+ {
+ }
+
+ template <typename FunctionType>
+ cmCommandLineArgument(std::string n, std::string failedMsg, Values t,
+ FunctionType&& func)
+ : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n))
+ , InvalidValueMessage(std::move(failedMsg))
+ , Name(std::move(n))
+ , Type(t)
+ , StoreCall(std::forward<FunctionType>(func))
+ {
+ }
+
+ bool matches(std::string const& input) const
+ {
+ return (this->Type == Values::Zero) ? (input == this->Name)
+ : cmHasPrefix(input, this->Name);
+ }
+
+ template <typename T, typename... CallState>
+ bool parse(std::string const& input, T& index,
+ std::vector<std::string> const& allArgs,
+ CallState&&... state) const
+ {
+ enum class ParseMode
+ {
+ Valid,
+ Invalid,
+ SyntaxError,
+ ValueError
+ };
+ ParseMode parseState = ParseMode::Valid;
+
+ if (this->Type == Values::Zero) {
+ if (input.size() == this->Name.size()) {
+ parseState =
+ this->StoreCall(std::string{}, std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ } else {
+ parseState = ParseMode::SyntaxError;
+ }
+
+ } else if (this->Type == Values::One || this->Type == Values::ZeroOrOne) {
+ if (input.size() == this->Name.size()) {
+ ++index;
+ if (index >= allArgs.size() || allArgs[index][0] == '-') {
+ if (this->Type == Values::ZeroOrOne) {
+ parseState =
+ this->StoreCall(std::string{}, std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ } else {
+ parseState = ParseMode::ValueError;
+ }
+ } else {
+ parseState =
+ this->StoreCall(allArgs[index], std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ } else {
+ // parse the string to get the value
+ auto possible_value = cm::string_view(input).substr(this->Name.size());
+ if (possible_value.empty()) {
+ parseState = ParseMode::SyntaxError;
+ parseState = ParseMode::ValueError;
+ } else if (possible_value[0] == '=') {
+ possible_value.remove_prefix(1);
+ if (possible_value.empty()) {
+ parseState = ParseMode::ValueError;
+ } else {
+ parseState = this->StoreCall(std::string(possible_value),
+ std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ }
+ if (parseState == ParseMode::Valid) {
+ parseState = this->StoreCall(std::string(possible_value),
+ std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ }
+ } else if (this->Type == Values::Two) {
+ if (input.size() == this->Name.size()) {
+ if (index + 2 >= allArgs.size() || allArgs[index + 1][0] == '-' ||
+ allArgs[index + 2][0] == '-') {
+ parseState = ParseMode::ValueError;
+ } else {
+ index += 2;
+ parseState =
+ this->StoreCall(cmStrCat(allArgs[index - 1], ";", allArgs[index]),
+ std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ }
+ } else if (this->Type == Values::OneOrMore) {
+ if (input.size() == this->Name.size()) {
+ auto nextValueIndex = index + 1;
+ if (nextValueIndex >= allArgs.size() || allArgs[index + 1][0] == '-') {
+ parseState = ParseMode::ValueError;
+ } else {
+ std::string buffer = allArgs[nextValueIndex++];
+ while (nextValueIndex < allArgs.size() &&
+ allArgs[nextValueIndex][0] != '-') {
+ buffer = cmStrCat(buffer, ";", allArgs[nextValueIndex++]);
+ }
+ parseState =
+ this->StoreCall(buffer, std::forward<CallState>(state)...)
+ ? ParseMode::Valid
+ : ParseMode::Invalid;
+ }
+ }
+ }
+
+ if (parseState == ParseMode::SyntaxError) {
+ cmSystemTools::Error(this->InvalidSyntaxMessage);
+ } else if (parseState == ParseMode::ValueError) {
+ cmSystemTools::Error(this->InvalidValueMessage);
+ }
+ return (parseState == ParseMode::Valid);
+ }
+};
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index a853bb1..113751a 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -707,7 +707,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
break;
}
input.replace(pos, endPos - pos + 1, targetName);
- lastPos = endPos;
+ lastPos = pos + targetName.size();
}
pos = 0;
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 0f91d6d..c33fabd 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -898,7 +898,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmExpandList(compileRule, compileCommands);
}
- if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
+ if (this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS") &&
lang_can_export_cmds && compileCommands.size() == 1) {
std::string compileCommand = compileCommands[0];
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 18c9d82..f1bd760 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1536,7 +1536,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
std::string const& objectFileDir, std::string const& flags,
std::string const& defines, std::string const& includes)
{
- if (!this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS")) {
+ if (!this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS")) {
return;
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 2fd6063..1fd2355 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -383,6 +383,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("UNITY_BUILD");
initProp("UNITY_BUILD_UNIQUE_ID");
initProp("OPTIMIZE_DEPENDENCIES");
+ initProp("EXPORT_COMPILE_COMMANDS");
initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
initPropValue("UNITY_BUILD_MODE", "BATCH");
initPropValue("PCH_WARN_INVALID", "ON");
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 9c41504..a93a78a 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1897,8 +1897,15 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
}
// Figure out if there's any additional flags to use
if (cmProp saf = sf->GetProperty("VS_SHADER_FLAGS")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*saf);
+
for (const std::string& config : this->Configurations) {
- toolSettings[config]["AdditionalOptions"] = *saf;
+ std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+ if (!evaluated.empty()) {
+ toolSettings[config]["AdditionalOptions"] = evaluated;
+ }
}
}
// Figure out if debug information should be generated
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 1691037..d6360a7 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -29,6 +29,7 @@
#include "cm_sys_stat.h"
#include "cmCMakePresetsFile.h"
+#include "cmCommandLineArgument.h"
#include "cmCommands.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
@@ -132,131 +133,13 @@ namespace {
using JsonValueMapType = std::unordered_map<std::string, Json::Value>;
#endif
-struct CommandArgument
-{
- enum struct Values
- {
- Zero,
- One,
- Two,
- };
-
- std::string InvalidSyntaxMessage;
- std::string InvalidValueMessage;
- std::string Name;
- CommandArgument::Values Type;
- std::function<bool(std::string const& value, cmake* state)> StoreCall;
-
- template <typename FunctionType>
- CommandArgument(std::string n, CommandArgument::Values t,
- FunctionType&& func)
- : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n))
- , InvalidValueMessage(cmStrCat("Invalid value used with ", n))
- , Name(std::move(n))
- , Type(t)
- , StoreCall(std::forward<FunctionType>(func))
- {
- }
-
- template <typename FunctionType>
- CommandArgument(std::string n, std::string failedMsg,
- CommandArgument::Values t, FunctionType&& func)
- : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n))
- , InvalidValueMessage(std::move(failedMsg))
- , Name(std::move(n))
- , Type(t)
- , StoreCall(std::forward<FunctionType>(func))
- {
- }
-
- bool matches(std::string const& input) const
- {
- return cmHasPrefix(input, this->Name);
- }
-
- template <typename T>
- bool parse(std::string const& input, T& index,
- std::vector<std::string> const& allArgs, cmake* state) const
- {
- enum struct ParseMode
- {
- Valid,
- Invalid,
- SyntaxError,
- ValueError
- };
- ParseMode parseState = ParseMode::Valid;
-
- // argument is the next parameter
- if (this->Type == CommandArgument::Values::Zero) {
- if (input.size() == this->Name.size()) {
- parseState = this->StoreCall(input, state) ? ParseMode::Valid
- : ParseMode::Invalid;
- } else {
- parseState = ParseMode::SyntaxError;
- }
-
- } else if (this->Type == CommandArgument::Values::One) {
- if (input.size() == this->Name.size()) {
- ++index;
- if (index >= allArgs.size() || allArgs[index][0] == '-') {
- parseState = ParseMode::ValueError;
- } else {
- parseState = this->StoreCall(allArgs[index], state)
- ? ParseMode::Valid
- : ParseMode::Invalid;
- }
- } else {
- // parse the string to get the value
- auto possible_value = cm::string_view(input).substr(this->Name.size());
- if (possible_value.empty()) {
- parseState = ParseMode::SyntaxError;
- parseState = ParseMode::ValueError;
- } else if (possible_value[0] == '=') {
- possible_value.remove_prefix(1);
- if (possible_value.empty()) {
- parseState = ParseMode::ValueError;
- } else {
- parseState = this->StoreCall(std::string(possible_value), state)
- ? ParseMode::Valid
- : ParseMode::Invalid;
- }
- }
- if (parseState == ParseMode::Valid) {
- parseState = this->StoreCall(std::string(possible_value), state)
- ? ParseMode::Valid
- : ParseMode::Invalid;
- }
- }
- } else if (this->Type == CommandArgument::Values::Two) {
- if (input.size() == this->Name.size()) {
- if (index + 2 >= allArgs.size() || allArgs[index + 1][0] == '-' ||
- allArgs[index + 2][0] == '-') {
- parseState = ParseMode::ValueError;
- } else {
- index += 2;
- parseState =
- this->StoreCall(cmStrCat(allArgs[index - 1], ";", allArgs[index]),
- state)
- ? ParseMode::Valid
- : ParseMode::Invalid;
- }
- }
- }
-
- if (parseState == ParseMode::SyntaxError) {
- cmSystemTools::Error(this->InvalidSyntaxMessage);
- } else if (parseState == ParseMode::ValueError) {
- cmSystemTools::Error(this->InvalidValueMessage);
- }
- return (parseState == ParseMode::Valid);
- }
-};
-
auto IgnoreAndTrueLambda = [](std::string const&, cmake*) -> bool {
return true;
};
+using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value, cmake* state)>;
+
} // namespace
static bool cmakeCheckStampFile(const std::string& stampName);
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index f7734a6..ba471b7 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <cassert>
-#include <cctype>
#include <climits>
#include <cstring>
#include <iostream>
@@ -19,6 +18,7 @@
#include <cm3p/uv.h>
+#include "cmCommandLineArgument.h"
#include "cmConsoleBuf.h"
#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmGlobalGenerator.h"
@@ -213,61 +213,114 @@ int do_cmake(int ac, char const* const* av)
}
#endif
+ bool wizard_mode = false;
bool sysinfo = false;
bool list_cached = false;
bool list_all_cached = false;
bool list_help = false;
bool view_only = false;
cmake::WorkingMode workingMode = cmake::NORMAL_MODE;
- std::vector<std::string> args;
- for (int i = 0; i < ac; ++i) {
- if (strcmp(av[i], "-i") == 0) {
- /* clang-format off */
- std::cerr <<
- "The \"cmake -i\" wizard mode is no longer supported.\n"
- "Use the -D option to set cache values on the command line.\n"
- "Use cmake-gui or ccmake for an interactive dialog.\n";
- /* clang-format on */
- return 1;
- }
- if (strcmp(av[i], "--system-information") == 0) {
- sysinfo = true;
- } else if (strcmp(av[i], "-N") == 0) {
- view_only = true;
- } else if (strcmp(av[i], "-L") == 0) {
- list_cached = true;
- } else if (strcmp(av[i], "-LA") == 0) {
- list_all_cached = true;
- } else if (strcmp(av[i], "-LH") == 0) {
- list_cached = true;
- list_help = true;
- } else if (strcmp(av[i], "-LAH") == 0) {
- list_all_cached = true;
- list_help = true;
- } else if (cmHasLiteralPrefix(av[i], "-P")) {
- if (i == ac - 1) {
- cmSystemTools::Error("No script specified for argument -P");
- return 1;
+ std::vector<std::string> parsedArgs;
+
+ using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value)>;
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{
+ "-i", CommandArgument::Values::Zero,
+ [&wizard_mode](std::string const&) -> bool {
+ /* clang-format off */
+ std::cerr <<
+ "The \"cmake -i\" wizard mode is no longer supported.\n"
+ "Use the -D option to set cache values on the command line.\n"
+ "Use cmake-gui or ccmake for an interactive dialog.\n";
+ /* clang-format on */
+ wizard_mode = true;
+ return true;
+ } },
+ CommandArgument{ "--system-information", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ sysinfo = true;
+ return true;
+ } },
+ CommandArgument{ "-N", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ view_only = true;
+ return true;
+ } },
+ CommandArgument{ "-LAH", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ list_all_cached = true;
+ list_help = true;
+ return true;
+ } },
+ CommandArgument{ "-LA", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ list_all_cached = true;
+ return true;
+ } },
+ CommandArgument{ "-LH", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ list_cached = true;
+ list_help = true;
+ return true;
+ } },
+ CommandArgument{ "-L", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ list_cached = true;
+ return true;
+ } },
+ CommandArgument{ "-P", "No script specified for argument -P",
+ CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ workingMode = cmake::SCRIPT_MODE;
+ parsedArgs.emplace_back("-P");
+ parsedArgs.push_back(value);
+ return true;
+ } },
+ CommandArgument{ "--find-package", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ workingMode = cmake::FIND_PACKAGE_MODE;
+ parsedArgs.emplace_back("--find-package");
+ return true;
+ } },
+ CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ workingMode = cmake::HELP_MODE;
+ parsedArgs.emplace_back("--list-presets");
+ return true;
+ } },
+ };
+
+ std::vector<std::string> inputArgs;
+ inputArgs.reserve(ac);
+ cm::append(inputArgs, av, av + ac);
+
+ for (decltype(inputArgs.size()) i = 0; i < inputArgs.size(); ++i) {
+ std::string const& arg = inputArgs[i];
+ bool matched = false;
+ for (auto const& m : arguments) {
+ if (m.matches(arg)) {
+ matched = true;
+ if (m.parse(arg, i, inputArgs)) {
+ break;
+ }
+ return 1; // failed to parse
}
- workingMode = cmake::SCRIPT_MODE;
- args.emplace_back(av[i]);
- i++;
- args.emplace_back(av[i]);
- } else if (cmHasLiteralPrefix(av[i], "--find-package")) {
- workingMode = cmake::FIND_PACKAGE_MODE;
- args.emplace_back(av[i]);
- } else if (strcmp(av[i], "--list-presets") == 0) {
- workingMode = cmake::HELP_MODE;
- args.emplace_back(av[i]);
- } else {
- args.emplace_back(av[i]);
}
+ if (!matched) {
+ parsedArgs.emplace_back(av[i]);
+ }
+ }
+
+ if (wizard_mode) {
+ return 1;
}
+
if (sysinfo) {
cmake cm(cmake::RoleProject, cmState::Project);
cm.SetHomeDirectory("");
cm.SetHomeOutputDirectory("");
- int ret = cm.GetSystemInformation(args);
+ int ret = cm.GetSystemInformation(parsedArgs);
return ret;
}
cmake::Role const role =
@@ -297,7 +350,7 @@ int do_cmake(int ac, char const* const* av)
});
cm.SetWorkingMode(workingMode);
- int res = cm.Run(args, view_only);
+ int res = cm.Run(parsedArgs, view_only);
if (list_cached || list_all_cached) {
std::cout << "-- Cache values" << std::endl;
std::vector<std::string> keys = cm.GetState()->GetCacheEntryKeys();
@@ -332,16 +385,9 @@ int do_cmake(int ac, char const* const* av)
}
#ifndef CMAKE_BOOTSTRAP
-int extract_job_number(int& index, char const* current, char const* next,
- int len_of_flag)
+int extract_job_number(std::string const& command,
+ std::string const& jobString)
{
- std::string command(current);
- std::string jobString = command.substr(len_of_flag);
- if (jobString.empty() && next && isdigit(next[0])) {
- ++index; // skip parsing the job number
- jobString = std::string(next);
- }
-
int jobs = -1;
unsigned long numJobs = 0;
if (jobString.empty()) {
@@ -356,8 +402,8 @@ int extract_job_number(int& index, char const* current, char const* next,
jobs = int(numJobs);
}
} else {
- std::cerr << "'" << command.substr(0, len_of_flag) << "' invalid number '"
- << jobString << "' given.\n\n";
+ std::cerr << "'" << command << "' invalid number '" << jobString
+ << "' given.\n\n";
}
return jobs;
}
@@ -374,88 +420,107 @@ int do_build(int ac, char const* const* av)
std::string config;
std::string dir;
std::vector<std::string> nativeOptions;
+ bool nativeOptionsPassed = false;
bool cleanFirst = false;
bool foundClean = false;
bool foundNonClean = false;
bool verbose = cmSystemTools::HasEnv("VERBOSE");
- enum Doing
- {
- DoingNone,
- DoingDir,
- DoingTarget,
- DoingConfig,
- DoingNative
+ auto jLambda = [&](std::string const& value) -> bool {
+ jobs = extract_job_number("-j", value);
+ if (jobs < 0) {
+ dir.clear();
+ }
+ return true;
};
- Doing doing = DoingDir;
- for (int i = 2; i < ac; ++i) {
- if (doing == DoingNative) {
- nativeOptions.emplace_back(av[i]);
- } else if (cmHasLiteralPrefix(av[i], "-j")) {
- const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr);
- jobs = extract_job_number(i, av[i], nextArg, sizeof("-j") - 1);
- if (jobs < 0) {
- dir.clear();
- }
- doing = DoingNone;
- } else if (cmHasLiteralPrefix(av[i], "--parallel")) {
- const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr);
- jobs = extract_job_number(i, av[i], nextArg, sizeof("--parallel") - 1);
- if (jobs < 0) {
- dir.clear();
+ auto parallelLambda = [&](std::string const& value) -> bool {
+ jobs = extract_job_number("--parallel", value);
+ if (jobs < 0) {
+ dir.clear();
+ }
+ return true;
+ };
+ auto targetLambda = [&](std::string const& value) -> bool {
+ if (!value.empty()) {
+ std::vector<std::string> values = cmExpandedList(value);
+ for (auto const& v : values) {
+ targets.emplace_back(v);
+ if (v == "clean") {
+ foundClean = true;
+ } else {
+ foundNonClean = true;
+ }
}
- doing = DoingNone;
- } else if ((strcmp(av[i], "--target") == 0) ||
- (strcmp(av[i], "-t") == 0)) {
- doing = DoingTarget;
- } else if (strcmp(av[i], "--config") == 0) {
- doing = DoingConfig;
- } else if (strcmp(av[i], "--clean-first") == 0) {
- cleanFirst = true;
- doing = DoingNone;
- } else if ((strcmp(av[i], "--verbose") == 0) ||
- (strcmp(av[i], "-v") == 0)) {
- verbose = true;
- doing = DoingNone;
- } else if (strcmp(av[i], "--use-stderr") == 0) {
- /* tolerate legacy option */
- } else if (strcmp(av[i], "--") == 0) {
- doing = DoingNative;
- } else {
- switch (doing) {
- case DoingDir:
- dir = cmSystemTools::CollapseFullPath(av[i]);
- doing = DoingNone;
- break;
- case DoingTarget:
- if (strlen(av[i]) == 0) {
- std::cerr << "Warning: Argument number " << i
- << " after --target option is empty." << std::endl;
- } else {
- targets.emplace_back(av[i]);
- if (strcmp(av[i], "clean") == 0) {
- foundClean = true;
- } else {
- foundNonClean = true;
- }
- }
- if (foundClean && foundNonClean) {
- std::cerr << "Error: Building 'clean' and other targets together "
- "is not supported."
- << std::endl;
- dir.clear();
- }
- break;
- case DoingConfig:
- config = av[i];
- doing = DoingNone;
- break;
- default:
- std::cerr << "Unknown argument " << av[i] << std::endl;
- dir.clear();
+ return true;
+ }
+ return false;
+ };
+ auto verboseLambda = [&](std::string const&) -> bool {
+ verbose = true;
+ return true;
+ };
+
+ using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value)>;
+
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, jLambda },
+ CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne,
+ parallelLambda },
+ CommandArgument{ "-t", CommandArgument::Values::OneOrMore, targetLambda },
+ CommandArgument{ "--target", CommandArgument::Values::OneOrMore,
+ targetLambda },
+ CommandArgument{ "--config", CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ config = value;
+ return true;
+ } },
+ CommandArgument{ "--clean-first", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ cleanFirst = true;
+ return true;
+ } },
+ CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda },
+ CommandArgument{ "--verbose", CommandArgument::Values::Zero,
+ verboseLambda },
+ /* legacy option no-op*/
+ CommandArgument{ "--use-stderr", CommandArgument::Values::Zero,
+ [](std::string const&) -> bool { return true; } },
+ CommandArgument{ "--", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ nativeOptionsPassed = true;
+ return true;
+ } },
+ };
+
+ if (ac >= 3) {
+ dir = cmSystemTools::CollapseFullPath(av[2]);
+
+ std::vector<std::string> inputArgs;
+ inputArgs.reserve(ac - 3);
+ cm::append(inputArgs, av + 3, av + ac);
+
+ decltype(inputArgs.size()) i = 0;
+ for (; i < inputArgs.size() && !nativeOptionsPassed; ++i) {
+
+ std::string const& arg = inputArgs[i];
+ for (auto const& m : arguments) {
+ if (m.matches(arg) && m.parse(arg, i, inputArgs)) {
break;
+ }
}
}
+
+ if (nativeOptionsPassed) {
+ cm::append(nativeOptions, inputArgs.begin() + i, inputArgs.end());
+ }
+ }
+
+ if (foundClean && foundNonClean) {
+ std::cerr << "Error: Building 'clean' and other targets together "
+ "is not supported."
+ << std::endl;
+ dir.clear();
}
if (jobs == cmake::NO_BUILD_PARALLEL_LEVEL) {
@@ -658,60 +723,59 @@ int do_install(int ac, char const* const* av)
bool strip = false;
bool verbose = cmSystemTools::HasEnv("VERBOSE");
- enum Doing
- {
- DoingNone,
- DoingDir,
- DoingConfig,
- DoingComponent,
- DoingPrefix,
- DoingDefaultDirectoryPermissions,
+ auto verboseLambda = [&](std::string const&) -> bool {
+ verbose = true;
+ return true;
};
- Doing doing = DoingDir;
+ using CommandArgument =
+ cmCommandLineArgument<bool(std::string const& value)>;
+
+ std::vector<CommandArgument> arguments = {
+ CommandArgument{ "--config", CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ config = value;
+ return true;
+ } },
+ CommandArgument{ "--component", CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ component = value;
+ return true;
+ } },
+ CommandArgument{ "--default-directory-permissions",
+ CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ defaultDirectoryPermissions = value;
+ return true;
+ } },
+ CommandArgument{ "--prefix", CommandArgument::Values::One,
+ [&](std::string const& value) -> bool {
+ prefix = value;
+ return true;
+ } },
+ CommandArgument{ "--strip", CommandArgument::Values::Zero,
+ [&](std::string const&) -> bool {
+ strip = true;
+ return true;
+ } },
+ CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda },
+ CommandArgument{ "--verbose", CommandArgument::Values::Zero,
+ verboseLambda }
+ };
- for (int i = 2; i < ac; ++i) {
- if (strcmp(av[i], "--config") == 0) {
- doing = DoingConfig;
- } else if (strcmp(av[i], "--component") == 0) {
- doing = DoingComponent;
- } else if (strcmp(av[i], "--prefix") == 0) {
- doing = DoingPrefix;
- } else if (strcmp(av[i], "--strip") == 0) {
- strip = true;
- doing = DoingNone;
- } else if ((strcmp(av[i], "--verbose") == 0) ||
- (strcmp(av[i], "-v") == 0)) {
- verbose = true;
- doing = DoingNone;
- } else if (strcmp(av[i], "--default-directory-permissions") == 0) {
- doing = DoingDefaultDirectoryPermissions;
- } else {
- switch (doing) {
- case DoingDir:
- dir = cmSystemTools::CollapseFullPath(av[i]);
- doing = DoingNone;
- break;
- case DoingConfig:
- config = av[i];
- doing = DoingNone;
- break;
- case DoingComponent:
- component = av[i];
- doing = DoingNone;
- break;
- case DoingPrefix:
- prefix = av[i];
- doing = DoingNone;
- break;
- case DoingDefaultDirectoryPermissions:
- defaultDirectoryPermissions = av[i];
- doing = DoingNone;
- break;
- default:
- std::cerr << "Unknown argument " << av[i] << std::endl;
- dir.clear();
+ if (ac >= 3) {
+ dir = cmSystemTools::CollapseFullPath(av[2]);
+
+ std::vector<std::string> inputArgs;
+ inputArgs.reserve(ac - 3);
+ cm::append(inputArgs, av + 3, av + ac);
+ for (decltype(inputArgs.size()) i = 0; i < inputArgs.size(); ++i) {
+
+ std::string const& arg = inputArgs[i];
+ for (auto const& m : arguments) {
+ if (m.matches(arg) && m.parse(arg, i, inputArgs)) {
break;
+ }
}
}
}