diff options
86 files changed, 1593 insertions, 710 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 38cc0d8..ec25596 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -119,6 +119,7 @@ Properties on Targets /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY /prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG /prop_tgt/ARCHIVE_OUTPUT_NAME + /prop_tgt/AUTOGEN_BUILD_DIR /prop_tgt/AUTOGEN_TARGET_DEPENDS /prop_tgt/AUTOMOC_DEPEND_FILTERS /prop_tgt/AUTOMOC_MOC_OPTIONS diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index 3b95b05..9f3968c 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst @@ -68,14 +68,24 @@ be included by the user in the C++ implementation file with a preprocessor ``#include``. Included ``moc_*.cpp`` and ``*.moc`` files will be generated in the -``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include`` directory which is +``<AUTOGEN_BUILD_DIR>/include`` directory which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. (This differs from CMake 3.7 and below; see their documentation for details.) +* For multi configuration generators, except Xcode, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + +* See :prop_tgt:`AUTOGEN_BUILD_DIR`. + Not included ``moc_<basename>.cpp`` files will be generated in custom folders to avoid name collisions and included in a separate -``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/moc_compilation.cpp`` -file which is compiled into the target. +``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp`` file which is compiled +into the target. + +* For multi configuration generators, except Xcode, the file is + ``<AUTOGEN_BUILD_DIR>/mocs_compilation_<CONFIG>.cpp``. + +* See :prop_tgt:`AUTOGEN_BUILD_DIR`. The ``moc`` command line will consume the :prop_tgt:`COMPILE_DEFINITIONS` and :prop_tgt:`INCLUDE_DIRECTORIES` target properties from the target it is being @@ -109,10 +119,15 @@ searched for first in the vicinity of including file and afterwards in the optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target. The generated generated ``ui_*.h`` files are placed in the -``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include`` directory which is +``<AUTOGEN_BUILD_DIR>/include`` directory which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. (This differs from CMake 3.7 and below; see their documentation for details.) +* For multi configuration generators, except Xcode, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + +* See :prop_tgt:`AUTOGEN_BUILD_DIR`. + The :prop_tgt:`AUTOUIC` target property may be pre-set for all following targets by setting the :variable:`CMAKE_AUTOUIC` variable. The :prop_tgt:`AUTOUIC_OPTIONS` target property may be populated to set options diff --git a/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst new file mode 100644 index 0000000..8db6ede --- /dev/null +++ b/Help/prop_tgt/AUTOGEN_BUILD_DIR.rst @@ -0,0 +1,17 @@ +AUTOGEN_BUILD_DIR +----------------- + +Directory where :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and :prop_tgt:`AUTORCC` +generate files for the target. + +The directory is created on demand and automatically added to the +:prop_dir:`ADDITIONAL_MAKE_CLEAN_FILES`. + +When unset or empty the directory ``<dir>/<target-name>_autogen`` is used where +``<dir>`` is :variable:`CMAKE_CURRENT_BINARY_DIR` and ``<target-name>`` +is :prop_tgt:`NAME`. + +By default :prop_tgt:`AUTOGEN_BUILD_DIR` is unset. + +See the :manual:`cmake-qt(7)` manual for more information on using CMake +with Qt. diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 7e10fde..81eff82 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -13,13 +13,17 @@ source files at build time and invoke moc accordingly. * If an ``#include`` statement like ``#include "moc_<basename>.cpp"`` is found, the ``Q_OBJECT`` or ``Q_GADGET`` macros are expected in an otherwise empty - line of the ``<basename>.h(xx)`` header file. ``moc`` is run on the header file to - generate ``moc_<basename>.cpp`` in the - ``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include`` directory - which is automatically added to the target's - :prop_tgt:`INCLUDE_DIRECTORIES`. This allows the compiler to find the - included ``moc_<basename>.cpp`` file regardless of the location the - original source. + line of the ``<basename>.h(xx)`` header file. ``moc`` is run on the header + file to generate ``moc_<basename>.cpp`` in the + ``<AUTOGEN_BUILD_DIR>/include`` directory which is automatically added + to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. + This allows the compiler to find the included ``moc_<basename>.cpp`` file + regardless of the location the original source. + + * For multi configuration generators, except Xcode, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + + * See :prop_tgt:`AUTOGEN_BUILD_DIR`. * If an ``#include`` statement like ``#include "<basename>.moc"`` is found, then ``Q_OBJECT`` or ``Q_GADGET`` macros are expected in the current source @@ -28,10 +32,19 @@ source files at build time and invoke moc accordingly. * Header files that are not included by an ``#include "moc_<basename>.cpp"`` statement are nonetheless scanned for ``Q_OBJECT`` or ``Q_GADGET`` macros. The resulting ``moc_<basename>.cpp`` files are generated in custom - directories and automatically included in the generated - ``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/moc_compilation.cpp`` file, - which is compiled as part of the target. The custom directories help to - avoid name collisions for moc files with the same ``<basename>``. + directories and automatically included in a generated + ``<AUTOGEN_BUILD_DIR>/mocs_compilation.cpp`` file, + which is compiled as part of the target. + + * For multi configuration generators, except Xcode, the file names are + ``moc_<basename>_<CONFIG>.cpp`` and + ``<AUTOGEN_BUILD_DIR>/mocs_compilation_<CONFIG>.cpp``. + + * The custom directories with checksum + based names help to avoid name collisions for moc files with the same + ``<basename>``. + + * See :prop_tgt:`AUTOGEN_BUILD_DIR`. * Additionally, header files with the same base name as a source file, (like ``<basename>.h``) or ``_p`` appended to the base name (like diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 91d95e5..4a08072 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -14,8 +14,13 @@ and invoke ``uic`` accordingly. If an ``#include`` statement like searched for first in the vicinity of ``source.cpp`` and afterwards in the optional :prop_tgt:`AUTOUIC_SEARCH_PATHS` of the target. ``uic`` is run on the ``foo.ui`` file to generate ``ui_foo.h`` in the directory -``<CMAKE_CURRENT_BINARY_DIR>/<TARGETNAME>_autogen/include``, -which is added to the target's :prop_tgt:`INCLUDE_DIRECTORIES` automatically. +``<AUTOGEN_BUILD_DIR>/include``, +which is automatically added to the target's :prop_tgt:`INCLUDE_DIRECTORIES`. + +* For multi configuration generators, except Xcode, the include directory is + ``<AUTOGEN_BUILD_DIR>/include_<CONFIG>``. + +* See :prop_tgt:`AUTOGEN_BUILD_DIR`. This property is initialized by the value of the :variable:`CMAKE_AUTOUIC` variable if it is set when a target is created. diff --git a/Help/release/dev/Autogen_build_dir.rst b/Help/release/dev/Autogen_build_dir.rst new file mode 100644 index 0000000..d11c00b --- /dev/null +++ b/Help/release/dev/Autogen_build_dir.rst @@ -0,0 +1,6 @@ +AutoGen build dir +----------------- + +* The new target property :prop_tgt:`AUTOGEN_BUILD_DIR` was introduced which + allows to set a custom output directory for + :prop_tgt:`AUTOMOC`, :prop_tgt:`AUTOUIC` and :prop_tgt:`AUTORCC`. diff --git a/Help/release/dev/FindProtobuf-export-macro.rst b/Help/release/dev/FindProtobuf-export-macro.rst new file mode 100644 index 0000000..43d9223 --- /dev/null +++ b/Help/release/dev/FindProtobuf-export-macro.rst @@ -0,0 +1,6 @@ +FindProtobuf-export-macro +------------------------- + +* The :module:`FindProtobuf` module :command:`protobuf_generate_cpp` + command gained an ``EXPORT_MACRO`` option to specify the name of + a DLL export markup macro. diff --git a/Modules/AutogenInfo.cmake.in b/Modules/AutogenInfo.cmake.in index 5e945bc..4e85474 100644 --- a/Modules/AutogenInfo.cmake.in +++ b/Modules/AutogenInfo.cmake.in @@ -1,12 +1,10 @@ -# Target names -set(AM_TARGET_NAME @_autogen_target_name@) -set(AM_ORIGIN_TARGET_NAME @_origin_target_name@) # Directories and files set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/") set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/") set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@") +set(AM_BUILD_DIR @_autogen_build_dir@) set(AM_SOURCES @_sources@) set(AM_HEADERS @_headers@) # Qt environment diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index b2fb4b7..cc273e0 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -208,6 +208,10 @@ # # Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake. +# Save project's policies +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + #------------------------------------------------------------------------------- # Before we go searching, check whether boost-cmake is available, unless the # user specifically asked NOT to search for boost-cmake. @@ -865,14 +869,12 @@ function(_Boost_MISSING_DEPENDENCIES componentvar extravar) list(APPEND _boost_processed_components ${_boost_unprocessed_components}) foreach(component ${_boost_unprocessed_components}) string(TOUPPER ${component} uppercomponent) - set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) + set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) _Boost_COMPONENT_DEPENDENCIES("${component}" _Boost_${uppercomponent}_DEPENDENCIES) set(_Boost_${uppercomponent}_DEPENDENCIES ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) foreach(componentdep ${_Boost_${uppercomponent}_DEPENDENCIES}) - list(FIND _boost_processed_components "${componentdep}" _boost_component_found) - list(FIND _boost_new_components "${componentdep}" _boost_component_new) - if (_boost_component_found EQUAL -1 AND _boost_component_new EQUAL -1) + if (NOT ("${componentdep}" IN_LIST _boost_processed_components OR "${componentdep}" IN_LIST _boost_new_components)) list(APPEND _boost_new_components ${componentdep}) endif() endforeach() @@ -1499,8 +1501,7 @@ endif() _Boost_MISSING_DEPENDENCIES(Boost_FIND_COMPONENTS _Boost_EXTRA_FIND_COMPONENTS) # If thread is required, get the thread libs as a dependency -list(FIND Boost_FIND_COMPONENTS thread _Boost_THREAD_DEPENDENCY_LIBS) -if(NOT _Boost_THREAD_DEPENDENCY_LIBS EQUAL -1) +if("thread" IN_LIST Boost_FIND_COMPONENTS) include(CMakeFindDependencyMacro) find_dependency(Threads) endif() @@ -1925,3 +1926,6 @@ list(REMOVE_DUPLICATES _Boost_COMPONENTS_SEARCHED) list(SORT _Boost_COMPONENTS_SEARCHED) set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}" CACHE INTERNAL "Components requested for this build tree.") + +# Restore project's policies +cmake_policy(POP) diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake index abc7518..33262f3 100644 --- a/Modules/FindProtobuf.cmake +++ b/Modules/FindProtobuf.cmake @@ -76,6 +76,7 @@ # include_directories(${Protobuf_INCLUDE_DIRS}) # include_directories(${CMAKE_CURRENT_BINARY_DIR}) # protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto) +# protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto) # protobuf_generate_python(PROTO_PY foo.proto) # add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS}) # target_link_libraries(bar ${Protobuf_LIBRARIES}) @@ -89,12 +90,15 @@ # # Add custom commands to process ``.proto`` files to C++:: # -# protobuf_generate_cpp (<SRCS> <HDRS> [<ARGN>...]) +# protobuf_generate_cpp (<SRCS> <HDRS> [EXPORT_MACRO <MACRO>] [<ARGN>...]) # # ``SRCS`` # Variable to define with autogenerated source files # ``HDRS`` # Variable to define with autogenerated header files +# ``EXPORT_MACRO`` +# is a macro which should expand to ``__declspec(dllexport)`` or +# ``__declspec(dllimport)`` depending on what is being compiled. # ``ARGN`` # ``.proto`` files # @@ -110,14 +114,21 @@ # ``.proto`` filess function(PROTOBUF_GENERATE_CPP SRCS HDRS) - if(NOT ARGN) + cmake_parse_arguments(protobuf "" "EXPORT_MACRO" "" ${ARGN}) + + set(PROTO_FILES "${protobuf_UNPARSED_ARGUMENTS}") + if(NOT PROTO_FILES) message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files") return() endif() + if(protobuf_EXPORT_MACRO) + set(DLL_EXPORT_DECL "dllexport_decl=${protobuf_EXPORT_MACRO}:") + endif() + if(PROTOBUF_GENERATE_CPP_APPEND_PATH) # Create an include path for each file specified - foreach(FIL ${ARGN}) + foreach(FIL ${PROTO_FILES}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(ABS_PATH ${ABS_FIL} PATH) list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) @@ -145,7 +156,7 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS) set(${SRCS}) set(${HDRS}) - foreach(FIL ${ARGN}) + foreach(FIL ${PROTO_FILES}) get_filename_component(ABS_FIL ${FIL} ABSOLUTE) get_filename_component(FIL_WE ${FIL} NAME_WE) if(NOT PROTOBUF_GENERATE_CPP_APPEND_PATH) @@ -162,7 +173,7 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS) OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc" "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h" COMMAND ${Protobuf_PROTOC_EXECUTABLE} - ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL} + ARGS "--cpp_out=${DLL_EXPORT_DECL}${CMAKE_CURRENT_BINARY_DIR}" ${_protobuf_include_path} ${ABS_FIL} DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE} COMMENT "Running C++ protocol buffer compiler on ${FIL}" VERBATIM ) diff --git a/Modules/FindXMLRPC.cmake b/Modules/FindXMLRPC.cmake index dd9dffc..f0b2583 100644 --- a/Modules/FindXMLRPC.cmake +++ b/Modules/FindXMLRPC.cmake @@ -36,13 +36,13 @@ find_program(XMLRPC_C_CONFIG NAMES xmlrpc-c-config) # Check whether we found anything. if(XMLRPC_C_CONFIG) - set(XMLRPC_FOUND 1) + set(XMLRPC_C_FOUND 1) else() - set(XMLRPC_FOUND 0) + set(XMLRPC_C_FOUND 0) endif() # Lookup the include directories needed for the components requested. -if(XMLRPC_FOUND) +if(XMLRPC_C_FOUND) # Use the newer EXECUTE_PROCESS command if it is available. if(COMMAND EXECUTE_PROCESS) execute_process( @@ -74,12 +74,12 @@ if(XMLRPC_FOUND) endforeach() else() message("Error running ${XMLRPC_C_CONFIG}: [${XMLRPC_C_CONFIG_RESULT}]") - set(XMLRPC_FOUND 0) + set(XMLRPC_C_FOUND 0) endif() endif() # Lookup the libraries needed for the components requested. -if(XMLRPC_FOUND) +if(XMLRPC_C_FOUND) # Use the newer EXECUTE_PROCESS command if it is available. if(COMMAND EXECUTE_PROCESS) execute_process( @@ -123,7 +123,7 @@ if(XMLRPC_FOUND) # If any library is not found then the whole package is not found. if(NOT XMLRPC_${name}_LIBRARY) - set(XMLRPC_FOUND 0) + set(XMLRPC_C_FOUND 0) endif() # Build an ordered list of all the libraries needed. @@ -131,19 +131,13 @@ if(XMLRPC_FOUND) endforeach() else() message("Error running ${XMLRPC_C_CONFIG}: [${XMLRPC_C_CONFIG_RESULT}]") - set(XMLRPC_FOUND 0) + set(XMLRPC_C_FOUND 0) endif() endif() # Report the results. -if(NOT XMLRPC_FOUND) - set(XMLRPC_DIR_MESSAGE - "XMLRPC was not found. Make sure the entries XMLRPC_* are set.") - if(NOT XMLRPC_FIND_QUIETLY) - message(STATUS "${XMLRPC_DIR_MESSAGE}") - else() - if(XMLRPC_FIND_REQUIRED) - message(FATAL_ERROR "${XMLRPC_DIR_MESSAGE}") - endif() - endif() -endif() +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +FIND_PACKAGE_HANDLE_STANDARD_ARGS( + XMLRPC + REQUIRED_VARS XMLRPC_C_FOUND XMLRPC_LIBRARIES XMLRPC_INCLUDE_DIRS + FAIL_MESSAGE "XMLRPC was not found. Make sure the entries XMLRPC_* are set.") diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a961f8d..42be644 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 8) -set(CMake_VERSION_PATCH 20170525) +set(CMake_VERSION_PATCH 20170528) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h index 96c5882..10deda4 100644 --- a/Source/CPack/cmCPackLog.h +++ b/Source/CPack/cmCPackLog.h @@ -85,12 +85,12 @@ public: //! Set the various prefixes for the logging. SetPrefix sets the generic // prefix that overwrittes missing ones. - void SetPrefix(std::string pfx) { this->Prefix = pfx; } - void SetOutputPrefix(std::string pfx) { this->OutputPrefix = pfx; } - void SetVerbosePrefix(std::string pfx) { this->VerbosePrefix = pfx; } - void SetDebugPrefix(std::string pfx) { this->DebugPrefix = pfx; } - void SetWarningPrefix(std::string pfx) { this->WarningPrefix = pfx; } - void SetErrorPrefix(std::string pfx) { this->ErrorPrefix = pfx; } + void SetPrefix(std::string const& pfx) { this->Prefix = pfx; } + void SetOutputPrefix(std::string const& pfx) { this->OutputPrefix = pfx; } + void SetVerbosePrefix(std::string const& pfx) { this->VerbosePrefix = pfx; } + void SetDebugPrefix(std::string const& pfx) { this->DebugPrefix = pfx; } + void SetWarningPrefix(std::string const& pfx) { this->WarningPrefix = pfx; } + void SetErrorPrefix(std::string const& pfx) { this->ErrorPrefix = pfx; } private: bool Verbose; diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index 0d01493..5db6e09 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -24,7 +24,7 @@ bool cmAddCustomTargetCommand::InitialPass( return false; } - std::string targetName = args[0]; + std::string const& targetName = args[0]; // Check the target name. if (targetName.find_first_of("/\\") != targetName.npos) { diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index e49d5d5..a73b57e 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -19,7 +19,7 @@ bool cmAddDependenciesCommand::InitialPass( return false; } - std::string target_name = args[0]; + std::string const& target_name = args[0]; if (this->Makefile->IsAlias(target_name)) { std::ostringstream e; e << "Cannot add target-level dependencies to alias target \"" diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index aae1085..1d0376f 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -24,7 +24,7 @@ bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args, } std::vector<std::string>::const_iterator s = args.begin(); - std::string exename = *s; + std::string const& exename = *s; ++s; bool use_win32 = false; diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 0bdf963..ebf1763 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -37,7 +37,7 @@ bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args, std::vector<std::string>::const_iterator s = args.begin(); - std::string libName = *s; + std::string const& libName = *s; ++s; diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx index dbd4dd1..1727ca5 100644 --- a/Source/cmAddSubDirectoryCommand.cxx +++ b/Source/cmAddSubDirectoryCommand.cxx @@ -20,7 +20,7 @@ bool cmAddSubDirectoryCommand::InitialPass( } // store the binpath - std::string srcArg = args[0]; + std::string const& srcArg = args[0]; std::string binArg; bool excludeFromAll = false; diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx index c92c47b..847a416 100644 --- a/Source/cmAuxSourceDirectoryCommand.cxx +++ b/Source/cmAuxSourceDirectoryCommand.cxx @@ -18,13 +18,13 @@ class cmExecutionStatus; bool cmAuxSourceDirectoryCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus&) { - if (args.size() < 2 || args.size() > 2) { + if (args.size() != 2) { this->SetError("called with incorrect number of arguments"); return false; } std::string sourceListValue; - std::string templateDirectory = args[0]; + std::string const& templateDirectory = args[0]; std::string tdir; if (!cmSystemTools::FileIsFullPath(templateDirectory.c_str())) { tdir = this->Makefile->GetCurrentSourceDirectory(); @@ -54,7 +54,7 @@ bool cmAuxSourceDirectoryCommand::InitialPass( std::string ext = file.substr(dotpos + 1); std::string base = file.substr(0, dotpos); // Process only source files - std::vector<std::string> srcExts = + std::vector<std::string> const& srcExts = this->Makefile->GetCMakeInstance()->GetSourceExtensions(); if (!base.empty() && std::find(srcExts.begin(), srcExts.end(), ext) != srcExts.end()) { diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx index 6836151..fd87600 100644 --- a/Source/cmBuildCommand.cxx +++ b/Source/cmBuildCommand.cxx @@ -32,7 +32,7 @@ bool cmBuildCommand::MainSignature(std::vector<std::string> const& args) } // The cmake variable in which to store the result. - const char* variable = args[0].c_str(); + std::string const& variable = args[0]; // Parse remaining arguments. std::string configuration; @@ -104,7 +104,7 @@ bool cmBuildCommand::TwoArgsSignature(std::vector<std::string> const& args) return false; } - const char* define = args[0].c_str(); + std::string const& define = args[0]; const char* cacheValue = this->Makefile->GetDefinition(define); std::string configType; diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx index e135ac6..4475c5a 100644 --- a/Source/cmCMakeHostSystemInformationCommand.cxx +++ b/Source/cmCMakeHostSystemInformationCommand.cxx @@ -26,7 +26,7 @@ bool cmCMakeHostSystemInformationCommand::InitialPass( return false; } - std::string variable = args[current_index + 1]; + std::string const& variable = args[current_index + 1]; current_index += 2; if (args.size() < (current_index + 2) || args[current_index] != "QUERY") { @@ -41,7 +41,7 @@ bool cmCMakeHostSystemInformationCommand::InitialPass( std::string result_list; for (size_t i = current_index + 1; i < args.size(); ++i) { - std::string key = args[i]; + std::string const& key = args[i]; if (i != current_index + 1) { result_list += ";"; } diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index b9c7549..18005f2 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -19,7 +19,7 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args, return false; } - const char* inFile = args[0].c_str(); + std::string const& inFile = args[0]; if (!cmSystemTools::FileIsFullPath(inFile)) { this->InputFile = this->Makefile->GetCurrentSourceDirectory(); this->InputFile += "/"; @@ -38,7 +38,7 @@ bool cmConfigureFileCommand::InitialPass(std::vector<std::string> const& args, return false; } - const char* outFile = args[1].c_str(); + std::string const& outFile = args[1]; if (!cmSystemTools::FileIsFullPath(outFile)) { this->OutputFile = this->Makefile->GetCurrentBinaryDirectory(); this->OutputFile += "/"; diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx index 9a097f3..86a83da 100644 --- a/Source/cmDefinePropertyCommand.cxx +++ b/Source/cmDefinePropertyCommand.cxx @@ -20,23 +20,25 @@ bool cmDefinePropertyCommand::InitialPass(std::vector<std::string> const& args, // Get the scope in which to define the property. cmProperty::ScopeType scope; - if (args[0] == "GLOBAL") { + std::string const& scope_arg = args[0]; + + if (scope_arg == "GLOBAL") { scope = cmProperty::GLOBAL; - } else if (args[0] == "DIRECTORY") { + } else if (scope_arg == "DIRECTORY") { scope = cmProperty::DIRECTORY; - } else if (args[0] == "TARGET") { + } else if (scope_arg == "TARGET") { scope = cmProperty::TARGET; - } else if (args[0] == "SOURCE") { + } else if (scope_arg == "SOURCE") { scope = cmProperty::SOURCE_FILE; - } else if (args[0] == "TEST") { + } else if (scope_arg == "TEST") { scope = cmProperty::TEST; - } else if (args[0] == "VARIABLE") { + } else if (scope_arg == "VARIABLE") { scope = cmProperty::VARIABLE; - } else if (args[0] == "CACHED_VARIABLE") { + } else if (scope_arg == "CACHED_VARIABLE") { scope = cmProperty::CACHED_VARIABLE; } else { std::ostringstream e; - e << "given invalid scope " << args[0] << ". " + e << "given invalid scope " << scope_arg << ". " << "Valid scopes are " << "GLOBAL, DIRECTORY, TARGET, SOURCE, " << "TEST, VARIABLE, CACHED_VARIABLE."; diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 2dffcaa..5b7b827 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -353,7 +353,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( all_files_map_t allFiles; std::vector<std::string> cFiles; - std::vector<std::string> srcExts = + std::vector<std::string> const& srcExts = this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions(); for (std::vector<cmLocalGenerator*>::const_iterator lg = lgs.begin(); @@ -387,7 +387,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( bool isCFile = false; std::string lang = (*si)->GetLanguage(); if (lang == "C" || lang == "CXX") { - std::string srcext = (*si)->GetExtension(); + std::string const& srcext = (*si)->GetExtension(); for (std::vector<std::string>::const_iterator ext = srcExts.begin(); ext != srcExts.end(); ++ext) { @@ -398,7 +398,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( } } - std::string fullPath = (*si)->GetFullPath(); + std::string const& fullPath = (*si)->GetFullPath(); if (isCFile) { cFiles.push_back(fullPath); @@ -414,7 +414,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile( } } - std::vector<std::string> headerExts = + std::vector<std::string> const& headerExts = this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions(); // The following loop tries to add header files matching to implementation diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index 98eebe6..adab061 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -240,7 +240,7 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles( bool isCFile = false; std::string lang = (*si)->GetLanguage(); if (lang == "C" || lang == "CXX") { - std::string srcext = (*si)->GetExtension(); + std::string const& srcext = (*si)->GetExtension(); for (std::vector<std::string>::const_iterator ext = srcExts.begin(); ext != srcExts.end(); ++ext) { if (srcext == *ext) { @@ -600,9 +600,6 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile( // which may have an acompanying header, one for all other files std::string projectType; - std::vector<std::string> headerExts = - this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions(); - std::map<std::string, cmSourceFile*> cFiles; std::set<std::string> otherFiles; diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 8d1adc7..2a6ce98 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -453,7 +453,7 @@ void cmExtraEclipseCDT4Generator::WriteGroups( for (std::vector<const cmSourceFile*>::const_iterator fileIt = sFiles.begin(); fileIt != sFiles.end(); ++fileIt) { - std::string fullPath = (*fileIt)->GetFullPath(); + std::string const& fullPath = (*fileIt)->GetFullPath(); if (!cmSystemTools::FileIsDirectory(fullPath)) { std::string linkName4 = linkName3; @@ -508,7 +508,7 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml) for (std::vector<cmSourceFile*>::const_iterator sfIt = files.begin(); sfIt != files.end(); sfIt++) { // Add the file to the list of sources. - std::string source = (*sfIt)->GetFullPath(); + std::string const& source = (*sfIt)->GetFullPath(); cmSourceGroup* sourceGroup = makefile->FindSourceGroup(source.c_str(), sourceGroups); sourceGroup->AssignSource(*sfIt); diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index ff6e2b7..32a539c 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -110,7 +110,7 @@ bool cmFileCommand::InitialPass(std::vector<std::string> const& args, this->SetError("must be called with at least two arguments."); return false; } - std::string subCommand = args[0]; + std::string const& subCommand = args[0]; if (subCommand == "WRITE") { return this->HandleWriteCommand(args, false); } diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index a3100c4..f67f353 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -938,7 +938,7 @@ bool cmFindPackageCommand::FindConfig() bool cmFindPackageCommand::FindPrefixedConfig() { - std::vector<std::string>& prefixes = this->SearchPaths; + std::vector<std::string> const& prefixes = this->SearchPaths; for (std::vector<std::string>::const_iterator pi = prefixes.begin(); pi != prefixes.end(); ++pi) { if (this->SearchPrefix(*pi)) { @@ -950,7 +950,7 @@ bool cmFindPackageCommand::FindPrefixedConfig() bool cmFindPackageCommand::FindFrameworkConfig() { - std::vector<std::string>& prefixes = this->SearchPaths; + std::vector<std::string> const& prefixes = this->SearchPaths; for (std::vector<std::string>::const_iterator i = prefixes.begin(); i != prefixes.end(); ++i) { if (this->SearchFrameworkPrefix(*i)) { @@ -962,7 +962,7 @@ bool cmFindPackageCommand::FindFrameworkConfig() bool cmFindPackageCommand::FindAppBundleConfig() { - std::vector<std::string>& prefixes = this->SearchPaths; + std::vector<std::string> const& prefixes = this->SearchPaths; for (std::vector<std::string>::const_iterator i = prefixes.begin(); i != prefixes.end(); ++i) { if (this->SearchAppBundlePrefix(*i)) { diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx index 7962da6..5ba3326 100644 --- a/Source/cmGetCMakePropertyCommand.cxx +++ b/Source/cmGetCMakePropertyCommand.cxx @@ -20,7 +20,7 @@ bool cmGetCMakePropertyCommand::InitialPass( return false; } - std::string variable = args[0]; + std::string const& variable = args[0]; std::string output = "NOTFOUND"; if (args[1] == "VARIABLES") { diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx index 920e1a0..6cb8e19 100644 --- a/Source/cmGetDirectoryPropertyCommand.cxx +++ b/Source/cmGetDirectoryPropertyCommand.cxx @@ -20,7 +20,7 @@ bool cmGetDirectoryPropertyCommand::InitialPass( } std::vector<std::string>::const_iterator i = args.begin(); - std::string variable = *i; + std::string const& variable = *i; ++i; // get the directory argument if there is one diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx index 509ef95..1a5f08e 100644 --- a/Source/cmGetSourceFilePropertyCommand.cxx +++ b/Source/cmGetSourceFilePropertyCommand.cxx @@ -15,8 +15,8 @@ bool cmGetSourceFilePropertyCommand::InitialPass( this->SetError("called with incorrect number of arguments"); return false; } - const char* var = args[0].c_str(); - const char* file = args[1].c_str(); + std::string const& var = args[0]; + std::string const& file = args[1]; cmSourceFile* sf = this->Makefile->GetSource(file); // for the location we must create a source file first diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx index 2379292..0910a53 100644 --- a/Source/cmGetTargetPropertyCommand.cxx +++ b/Source/cmGetTargetPropertyCommand.cxx @@ -22,8 +22,8 @@ bool cmGetTargetPropertyCommand::InitialPass( this->SetError("called with incorrect number of arguments"); return false; } - std::string var = args[0]; - const std::string& targetName = args[1]; + std::string const& var = args[0]; + std::string const& targetName = args[1]; std::string prop; bool prop_exists = false; diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx index a8a44b7..6424515 100644 --- a/Source/cmGetTestPropertyCommand.cxx +++ b/Source/cmGetTestPropertyCommand.cxx @@ -16,8 +16,8 @@ bool cmGetTestPropertyCommand::InitialPass( return false; } - std::string testName = args[0]; - std::string var = args[2]; + std::string const& testName = args[0]; + std::string const& var = args[2]; cmTest* test = this->Makefile->GetTest(testName); if (test) { const char* prop = CM_NULLPTR; diff --git a/Source/cmGlobalKdevelopGenerator.cxx b/Source/cmGlobalKdevelopGenerator.cxx index a958a17..e72c6e3 100644 --- a/Source/cmGlobalKdevelopGenerator.cxx +++ b/Source/cmGlobalKdevelopGenerator.cxx @@ -101,7 +101,7 @@ bool cmGlobalKdevelopGenerator::CreateFilelistFile( std::set<std::string> files; std::string tmp; - std::vector<std::string> hdrExts = + std::vector<std::string> const& hdrExts = this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions(); for (std::vector<cmLocalGenerator*>::const_iterator it = lgs.begin(); diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 88fcb12..e1e165c 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -56,7 +56,7 @@ void cmGlobalNinjaGenerator::Indent(std::ostream& os, int count) void cmGlobalNinjaGenerator::WriteDivider(std::ostream& os) { os << "# ======================================" - << "=======================================\n"; + "=======================================\n"; } void cmGlobalNinjaGenerator::WriteComment(std::ostream& os, diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index ba554aa..93e467c 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -75,29 +75,31 @@ bool cmInstallCommand::InitialPass(std::vector<std::string> const& args, this->DefaultComponentName = "Unspecified"; } + std::string const& mode = args[0]; + // Switch among the command modes. - if (args[0] == "SCRIPT") { + if (mode == "SCRIPT") { return this->HandleScriptMode(args); } - if (args[0] == "CODE") { + if (mode == "CODE") { return this->HandleScriptMode(args); } - if (args[0] == "TARGETS") { + if (mode == "TARGETS") { return this->HandleTargetsMode(args); } - if (args[0] == "FILES") { + if (mode == "FILES") { return this->HandleFilesMode(args); } - if (args[0] == "PROGRAMS") { + if (mode == "PROGRAMS") { return this->HandleFilesMode(args); } - if (args[0] == "DIRECTORY") { + if (mode == "DIRECTORY") { return this->HandleDirectoryMode(args); } - if (args[0] == "EXPORT") { + if (mode == "EXPORT") { return this->HandleExportMode(args); } - if (args[0] == "EXPORT_ANDROID_MK") { + if (mode == "EXPORT_ANDROID_MK") { return this->HandleExportAndroidMKMode(args); } @@ -165,7 +167,7 @@ bool cmInstallCommand::HandleScriptMode(std::vector<std::string> const& args) script.c_str(), false, component.c_str(), exclude_from_all)); } else if (doing_code) { doing_code = false; - std::string code = args[i]; + std::string const& code = args[i]; this->Makefile->AddInstallGenerator(new cmInstallScriptGenerator( code.c_str(), true, component.c_str(), exclude_from_all)); } diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx index 86fd46d..4a3b620 100644 --- a/Source/cmInstallFilesCommand.cxx +++ b/Source/cmInstallFilesCommand.cxx @@ -54,7 +54,7 @@ void cmInstallFilesCommand::FinalPass() } std::string testf; - std::string ext = this->FinalArgs[0]; + std::string const& ext = this->FinalArgs[0]; // two different options if (this->FinalArgs.size() > 1) { @@ -64,7 +64,7 @@ void cmInstallFilesCommand::FinalPass() // for each argument, get the files for (; s != this->FinalArgs.end(); ++s) { // replace any variables - std::string temps = *s; + std::string const& temps = *s; if (!cmSystemTools::GetFilenamePath(temps).empty()) { testf = cmSystemTools::GetFilenamePath(temps) + "/" + cmSystemTools::GetFilenameWithoutLastExtension(temps) + ext; @@ -78,7 +78,7 @@ void cmInstallFilesCommand::FinalPass() } else // reg exp list { std::vector<std::string> files; - std::string regex = this->FinalArgs[0]; + std::string const& regex = this->FinalArgs[0]; cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), regex, files); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 307024a..e48378d 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2258,7 +2258,7 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( { // Construct the object file name using the full path to the source // file which is its only unique identification. - const char* fullPath = source.GetFullPath().c_str(); + std::string const& fullPath = source.GetFullPath(); // Try referencing the source relative to the source tree. std::string relFromSource = diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index a8350b3..266710c 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -213,7 +213,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os) std::vector<std::string> pools; cmSystemTools::ExpandListArgument(jobpools, pools); for (size_t i = 0; i < pools.size(); ++i) { - const std::string pool = pools[i]; + std::string const& pool = pools[i]; const std::string::size_type eq = pool.find('='); unsigned int jobs; if (eq != std::string::npos && diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx index b2f0d22..14fd96f 100644 --- a/Source/cmMarkAsAdvancedCommand.cxx +++ b/Source/cmMarkAsAdvancedCommand.cxx @@ -30,7 +30,7 @@ bool cmMarkAsAdvancedCommand::InitialPass(std::vector<std::string> const& args, i = 1; } for (; i < args.size(); ++i) { - std::string variable = args[i]; + std::string const& variable = args[i]; cmState* state = this->Makefile->GetState(); if (!state->GetCacheEntryValue(variable)) { this->Makefile->GetCMakeInstance()->AddCacheEntry( diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx index 55451ff..5500eba 100644 --- a/Source/cmNewLineStyle.cxx +++ b/Source/cmNewLineStyle.cxx @@ -23,7 +23,7 @@ bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args, if (args[i] == "NEWLINE_STYLE") { size_t const styleIndex = i + 1; if (args.size() > styleIndex) { - const std::string eol = args[styleIndex]; + std::string const& eol = args[styleIndex]; if (eol == "LF" || eol == "UNIX") { NewLineStyle = LF; return true; diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx index 332fa83..beddc6e 100644 --- a/Source/cmOSXBundleGenerator.cxx +++ b/Source/cmOSXBundleGenerator.cxx @@ -48,8 +48,6 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, cmSystemTools::MakeDirectory(out.c_str()); this->Makefile->AddCMakeOutputFile(out); - std::string newoutpath = out; - // Configure the Info.plist file. Note that it needs the executable name // to be set. std::string plist = outpath; @@ -60,7 +58,7 @@ void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName, this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist.c_str()); this->Makefile->AddCMakeOutputFile(plist); - outpath = newoutpath; + outpath = out; } void cmOSXBundleGenerator::CreateFramework(const std::string& targetName, diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx index d47a047..d72c790 100644 --- a/Source/cmProjectCommand.cxx +++ b/Source/cmProjectCommand.cxx @@ -22,11 +22,14 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, this->SetError("PROJECT called with incorrect number of arguments"); return false; } - this->Makefile->SetProjectName(args[0]); - std::string bindir = args[0]; + std::string const& projectName = args[0]; + + this->Makefile->SetProjectName(projectName); + + std::string bindir = projectName; bindir += "_BINARY_DIR"; - std::string srcdir = args[0]; + std::string srcdir = projectName; srcdir += "_SOURCE_DIR"; this->Makefile->AddCacheDefinition( @@ -44,7 +47,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, this->Makefile->AddDefinition(srcdir, this->Makefile->GetCurrentSourceDirectory()); - this->Makefile->AddDefinition("PROJECT_NAME", args[0].c_str()); + this->Makefile->AddDefinition("PROJECT_NAME", projectName.c_str()); // Set the CMAKE_PROJECT_NAME variable to be the highest-level // project name in the tree. If there are two project commands @@ -54,10 +57,10 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, // will work. if (!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") || (this->Makefile->IsRootMakefile())) { - this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", args[0].c_str()); - this->Makefile->AddCacheDefinition("CMAKE_PROJECT_NAME", args[0].c_str(), - "Value Computed by CMake", - cmStateEnums::STATIC); + this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName.c_str()); + this->Makefile->AddCacheDefinition( + "CMAKE_PROJECT_NAME", projectName.c_str(), "Value Computed by CMake", + cmStateEnums::STATIC); } bool haveVersion = false; @@ -163,19 +166,19 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, } std::string vv; - vv = args[0] + "_VERSION"; + vv = projectName + "_VERSION"; this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str()); this->Makefile->AddDefinition(vv, vs.c_str()); - vv = args[0] + "_VERSION_MAJOR"; + vv = projectName + "_VERSION_MAJOR"; this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]); this->Makefile->AddDefinition(vv, vb[0]); - vv = args[0] + "_VERSION_MINOR"; + vv = projectName + "_VERSION_MINOR"; this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]); this->Makefile->AddDefinition(vv, vb[1]); - vv = args[0] + "_VERSION_PATCH"; + vv = projectName + "_VERSION_PATCH"; this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]); this->Makefile->AddDefinition(vv, vb[2]); - vv = args[0] + "_VERSION_TWEAK"; + vv = projectName + "_VERSION_TWEAK"; this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]); this->Makefile->AddDefinition(vv, vb[3]); } else if (cmp0048 != cmPolicies::OLD) { @@ -186,11 +189,11 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, vv.push_back("PROJECT_VERSION_MINOR"); vv.push_back("PROJECT_VERSION_PATCH"); vv.push_back("PROJECT_VERSION_TWEAK"); - vv.push_back(args[0] + "_VERSION"); - vv.push_back(args[0] + "_VERSION_MAJOR"); - vv.push_back(args[0] + "_VERSION_MINOR"); - vv.push_back(args[0] + "_VERSION_PATCH"); - vv.push_back(args[0] + "_VERSION_TWEAK"); + vv.push_back(projectName + "_VERSION"); + vv.push_back(projectName + "_VERSION_MAJOR"); + vv.push_back(projectName + "_VERSION_MINOR"); + vv.push_back(projectName + "_VERSION_PATCH"); + vv.push_back(projectName + "_VERSION_TWEAK"); std::string vw; for (std::vector<std::string>::iterator i = vv.begin(); i != vv.end(); ++i) { @@ -234,7 +237,7 @@ bool cmProjectCommand::InitialPass(std::vector<std::string> const& args, languages.push_back("CXX"); } this->Makefile->EnableLanguage(languages, false); - std::string extraInclude = "CMAKE_PROJECT_" + args[0] + "_INCLUDE"; + std::string extraInclude = "CMAKE_PROJECT_" + projectName + "_INCLUDE"; const char* include = this->Makefile->GetDefinition(extraInclude); if (include) { bool readit = this->Makefile->ReadDependentFile(include); diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 239b18d..e82665b 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -7,6 +7,7 @@ #include "cmCustomCommandLines.h" #include "cmFilePathChecksum.h" #include "cmGeneratorTarget.h" +#include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmOutputConverter.h" @@ -67,17 +68,19 @@ static std::string GetAutogenTargetFilesDir(cmGeneratorTarget const* target) targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); targetDir += "/"; targetDir += GetAutogenTargetName(target); - targetDir += ".dir/"; + targetDir += ".dir"; return targetDir; } static std::string GetAutogenTargetBuildDir(cmGeneratorTarget const* target) { - cmMakefile* makefile = target->Target->GetMakefile(); - std::string targetDir = makefile->GetCurrentBinaryDirectory(); - targetDir += "/"; - targetDir += GetAutogenTargetName(target); - targetDir += "/"; + std::string targetDir = GetSafeProperty(target, "AUTOGEN_BUILD_DIR"); + if (targetDir.empty()) { + cmMakefile* makefile = target->Target->GetMakefile(); + targetDir = makefile->GetCurrentBinaryDirectory(); + targetDir += "/"; + targetDir += GetAutogenTargetName(target); + } return targetDir; } @@ -151,6 +154,50 @@ static void GetCompileDefinitionsAndDirectories( } } +static bool IsMultiConfig(cmGlobalGenerator* globalGen) +{ + // FIXME: Xcode does not support per-config sources, yet. + // (EXCLUDED_SOURCE_FILE_NAMES) + // Treat it as a single configuration generator meanwhile. + if (globalGen->GetName().find("Xcode") != std::string::npos) { + return false; + } + return globalGen->IsMultiConfig(); +} + +static std::vector<std::string> GetConfigurations( + cmMakefile* makefile, std::string* config = CM_NULLPTR) +{ + std::vector<std::string> configs; + { + std::string cfg = makefile->GetConfigurations(configs); + if (config != CM_NULLPTR) { + *config = cfg; + } + } + // Add empty configuration on demand + if (configs.empty()) { + configs.push_back(""); + } + return configs; +} + +static std::vector<std::string> GetConfigurationSuffixes(cmMakefile* makefile) +{ + std::vector<std::string> suffixes; + if (IsMultiConfig(makefile->GetGlobalGenerator())) { + makefile->GetConfigurations(suffixes); + for (std::vector<std::string>::iterator it = suffixes.begin(); + it != suffixes.end(); ++it) { + it->insert(0, "_"); + } + } + if (suffixes.empty()) { + suffixes.push_back(""); + } + return suffixes; +} + static void AddDefinitionEscaped(cmMakefile* makefile, const char* key, const std::string& value) { @@ -220,6 +267,17 @@ static bool AddToSourceGroup(cmMakefile* makefile, const std::string& fileName, return true; } +static void AddGeneratedSource(cmMakefile* makefile, + const std::string& filename, + cmQtAutoGeneratorCommon::GeneratorType genType) +{ + cmSourceFile* gFile = makefile->GetOrCreateSource(filename, true); + gFile->SetProperty("GENERATED", "1"); + gFile->SetProperty("SKIP_AUTOGEN", "On"); + + AddToSourceGroup(makefile, filename, genType); +} + static void AcquireScanFiles(cmGeneratorTarget const* target, std::vector<std::string>& mocUicSources, std::vector<std::string>& mocUicHeaders, @@ -276,10 +334,11 @@ static void AcquireScanFiles(cmGeneratorTarget const* target, static void MocSetupAutoTarget( cmGeneratorTarget const* target, const std::string& autogenTargetName, - const std::string& qtMajorVersion, + std::string const& qtMajorVersion, std::string const& config, + std::vector<std::string> const& configs, std::vector<std::string> const& mocSkipList, - std::map<std::string, std::string>& configIncludes, - std::map<std::string, std::string>& configDefines) + std::map<std::string, std::string>& configMocIncludes, + std::map<std::string, std::string>& configMocDefines) { cmLocalGenerator* lg = target->GetLocalGenerator(); cmMakefile* makefile = target->Target->GetMakefile(); @@ -301,35 +360,26 @@ static void MocSetupAutoTarget( } // Moc includes and compile definitions { - std::string _moc_incs; - std::string _moc_compile_defs; - std::vector<std::string> configs; - { - const std::string& config = makefile->GetConfigurations(configs); - GetCompileDefinitionsAndDirectories(target, config, _moc_incs, - _moc_compile_defs); - AddDefinitionEscaped(makefile, "_moc_incs", _moc_incs); - AddDefinitionEscaped(makefile, "_moc_compile_defs", _moc_compile_defs); - } + // Default settings + std::string incs; + std::string compileDefs; + GetCompileDefinitionsAndDirectories(target, config, incs, compileDefs); + AddDefinitionEscaped(makefile, "_moc_incs", incs); + AddDefinitionEscaped(makefile, "_moc_compile_defs", compileDefs); + + // Configuration specific settings for (std::vector<std::string>::const_iterator li = configs.begin(); li != configs.end(); ++li) { - std::string config_moc_incs; - std::string config_moc_compile_defs; - GetCompileDefinitionsAndDirectories(target, *li, config_moc_incs, - config_moc_compile_defs); - if (config_moc_incs != _moc_incs) { - configIncludes[*li] = - cmOutputConverter::EscapeForCMake(config_moc_incs); - if (_moc_incs.empty()) { - _moc_incs = config_moc_incs; - } + std::string configIncs; + std::string configCompileDefs; + GetCompileDefinitionsAndDirectories(target, *li, configIncs, + configCompileDefs); + if (configIncs != incs) { + configMocIncludes[*li] = cmOutputConverter::EscapeForCMake(configIncs); } - if (config_moc_compile_defs != _moc_compile_defs) { - configDefines[*li] = - cmOutputConverter::EscapeForCMake(config_moc_compile_defs); - if (_moc_compile_defs.empty()) { - _moc_compile_defs = config_moc_compile_defs; - } + if (configCompileDefs != compileDefs) { + configMocDefines[*li] = + cmOutputConverter::EscapeForCMake(configCompileDefs); } } } @@ -375,7 +425,8 @@ static void UicGetOpts(cmGeneratorTarget const* target, } static void UicSetupAutoTarget( - cmGeneratorTarget const* target, const std::string& qtMajorVersion, + cmGeneratorTarget const* target, std::string const& qtMajorVersion, + std::string const& config, std::vector<std::string> const& configs, std::vector<std::string> const& uicSkipList, std::map<std::string, std::string>& configUicOptions) { @@ -396,25 +447,21 @@ static void UicSetupAutoTarget( } AddDefinitionEscaped(makefile, "_uic_search_paths", uicSearchPaths); } - // Uic target options { - std::string _uic_opts; - std::vector<std::string> configs; - UicGetOpts(target, makefile->GetConfigurations(configs), _uic_opts); - - AddDefinitionEscaped(makefile, "_uic_target_options", _uic_opts); + // Default settings + std::string uicOpts; + UicGetOpts(target, config, uicOpts); + AddDefinitionEscaped(makefile, "_uic_target_options", uicOpts); + // Configuration specific settings for (std::vector<std::string>::const_iterator li = configs.begin(); li != configs.end(); ++li) { - std::string config_uic_opts; - UicGetOpts(target, *li, config_uic_opts); - if (config_uic_opts != _uic_opts) { + std::string configUicOpts; + UicGetOpts(target, *li, configUicOpts); + if (configUicOpts != uicOpts) { configUicOptions[*li] = - cmOutputConverter::EscapeForCMake(config_uic_opts); - if (_uic_opts.empty()) { - _uic_opts = config_uic_opts; - } + cmOutputConverter::EscapeForCMake(configUicOpts); } } } @@ -623,14 +670,24 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenSources( { if (target->GetPropertyAsBool("AUTOMOC")) { cmMakefile* makefile = target->Target->GetMakefile(); - std::string mocCppFile = GetAutogenTargetBuildDir(target); - mocCppFile += "moc_compilation.cpp"; - { - cmSourceFile* gFile = makefile->GetOrCreateSource(mocCppFile, true); - gFile->SetProperty("SKIP_AUTOGEN", "On"); + const std::vector<std::string> suffixes = + GetConfigurationSuffixes(makefile); + // Get build directory + const std::string autogenBuildDir = GetAutogenTargetBuildDir(target); + // Register all compilation files as generated + for (std::vector<std::string>::const_iterator it = suffixes.begin(); + it != suffixes.end(); ++it) { + std::string mcFile = autogenBuildDir + "/mocs_compilation"; + mcFile += *it; + mcFile += ".cpp"; + AddGeneratedSource(makefile, mcFile, cmQtAutoGeneratorCommon::MOC); + } + // Mocs compilation file + if (IsMultiConfig(target->GetGlobalGenerator())) { + target->AddSource(autogenBuildDir + "/mocs_compilation_$<CONFIG>.cpp"); + } else { + target->AddSource(autogenBuildDir + "/mocs_compilation.cpp"); } - target->AddSource(mocCppFile); - AddToSourceGroup(makefile, mocCppFile, cmQtAutoGeneratorCommon::MOC); } } @@ -643,21 +700,30 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); + const bool multiConfig = IsMultiConfig(target->GetGlobalGenerator()); const std::string autogenTargetName = GetAutogenTargetName(target); const std::string autogenBuildDir = GetAutogenTargetBuildDir(target); const std::string workingDirectory = cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory()); const std::string qtMajorVersion = GetQtMajorVersion(target); const std::string rccCommand = RccGetExecutable(target, qtMajorVersion); + const std::vector<std::string> suffixes = GetConfigurationSuffixes(makefile); std::vector<std::string> autogenDepends; std::vector<std::string> autogenProvides; + // Remove build directories on cleanup + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + autogenBuildDir.c_str(), false); + // Remove old settings on cleanup { - std::string fname = GetAutogenTargetFilesDir(target); - fname += "/AutogenOldSettings.cmake"; - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", fname.c_str(), - false); + std::string base = GetAutogenTargetFilesDir(target); + for (std::vector<std::string>::const_iterator it = suffixes.begin(); + it != suffixes.end(); ++it) { + std::string fname = base + "/AutogenOldSettings" + *it + ".cmake"; + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", fname.c_str(), + false); + } } // Compose command lines @@ -698,22 +764,26 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( autogenComment = "Automatic " + tools + " for target " + target->GetName(); } - // Create autogen target build directory and add it to the clean files - cmSystemTools::MakeDirectory(autogenBuildDir); - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", - autogenBuildDir.c_str(), false); + // Add moc compilation to generated files list + if (mocEnabled) { + for (std::vector<std::string>::const_iterator it = suffixes.begin(); + it != suffixes.end(); ++it) { + std::string mcFile = autogenBuildDir + "/mocs_compilation"; + mcFile += *it; + mcFile += ".cpp"; + autogenProvides.push_back(mcFile); + } + } - // Create autogen target includes directory and - // add it to the origin target INCLUDE_DIRECTORIES + // Add autogen includes directory to the origin target INCLUDE_DIRECTORIES if (mocEnabled || uicEnabled) { - const std::string incsDir = autogenBuildDir + "include"; - cmSystemTools::MakeDirectory(incsDir); - target->AddIncludeDirectory(incsDir, true); - } + if (multiConfig) { + target->AddIncludeDirectory(autogenBuildDir + "/include_$<CONFIG>", + true); - // Register moc compilation file as generated - if (mocEnabled) { - autogenProvides.push_back(autogenBuildDir + "moc_compilation.cpp"); + } else { + target->AddIncludeDirectory(autogenBuildDir + "/include", true); + } } #if defined(_WIN32) && !defined(__CYGWIN__) @@ -755,7 +825,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( fileIt != srcFiles.end(); ++fileIt) { cmSourceFile* sf = *fileIt; if (!PropertyEnabled(sf, "SKIP_AUTOGEN")) { - const std::string ext = sf->GetExtension(); + std::string const& ext = sf->GetExtension(); // Add generated file that will be scanned by moc or uic to // the dependencies if (mocEnabled || uicEnabled) { @@ -784,23 +854,29 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Compose rcc output file name { - std::string rccOut = autogenBuildDir; - rccOut += fpathCheckSum.getPart(absFile); - rccOut += "/qrc_"; - rccOut += + std::string rccOutBase = autogenBuildDir + "/"; + rccOutBase += fpathCheckSum.getPart(absFile); + rccOutBase += "/qrc_"; + rccOutBase += cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile); - rccOut += ".cpp"; - - // Register rcc output file as generated - autogenProvides.push_back(rccOut); + // Register rcc ouput file as generated + for (std::vector<std::string>::const_iterator it = + suffixes.begin(); + it != suffixes.end(); ++it) { + std::string rccOutCfg = rccOutBase; + rccOutCfg += *it; + rccOutCfg += ".cpp"; + AddGeneratedSource(makefile, rccOutCfg, + cmQtAutoGeneratorCommon::RCC); + autogenProvides.push_back(rccOutCfg); + } // Add rcc output file to origin target sources - { - cmSourceFile* gFile = makefile->GetOrCreateSource(rccOut, true); - gFile->SetProperty("SKIP_AUTOGEN", "On"); + if (multiConfig) { + target->AddSource(rccOutBase + "_$<CONFIG>.cpp"); + } else { + target->AddSource(rccOutBase + ".cpp"); } - target->AddSource(rccOut); - AddToSourceGroup(makefile, rccOut, cmQtAutoGeneratorCommon::RCC); } if (PropertyEnabled(sf, "GENERATED")) { @@ -889,9 +965,25 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( cmMakefile::ScopePushPop varScope(makefile); static_cast<void>(varScope); + // Get configurations + std::string config; + const std::vector<std::string> configs(GetConfigurations(makefile, &config)); + + // Configurations settings buffers + std::map<std::string, std::string> configSuffix; std::map<std::string, std::string> configMocIncludes; std::map<std::string, std::string> configMocDefines; std::map<std::string, std::string> configUicOptions; + + // Configuration suffix + if (IsMultiConfig(target->GetGlobalGenerator())) { + for (std::vector<std::string>::const_iterator it = configs.begin(); + it != configs.end(); ++it) { + configSuffix[*it] = "_" + *it; + } + } + + // Basic setup { const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); @@ -899,45 +991,46 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( const std::string autogenTargetName = GetAutogenTargetName(target); const std::string qtMajorVersion = GetQtMajorVersion(target); - std::vector<std::string> _sources; - std::vector<std::string> _headers; + std::vector<std::string> sources; + std::vector<std::string> headers; if (mocEnabled || uicEnabled || rccEnabled) { std::vector<std::string> mocSkipList; std::vector<std::string> uicSkipList; - AcquireScanFiles(target, _sources, _headers, mocSkipList, uicSkipList); + AcquireScanFiles(target, sources, headers, mocSkipList, uicSkipList); if (mocEnabled) { - MocSetupAutoTarget(target, autogenTargetName, qtMajorVersion, - mocSkipList, configMocIncludes, configMocDefines); + MocSetupAutoTarget(target, autogenTargetName, qtMajorVersion, config, + configs, mocSkipList, configMocIncludes, + configMocDefines); } if (uicEnabled) { - UicSetupAutoTarget(target, qtMajorVersion, uicSkipList, - configUicOptions); + UicSetupAutoTarget(target, qtMajorVersion, config, configs, + uicSkipList, configUicOptions); } if (rccEnabled) { RccSetupAutoTarget(target, qtMajorVersion); } } - AddDefinitionEscaped(makefile, "_autogen_target_name", autogenTargetName); - AddDefinitionEscaped(makefile, "_origin_target_name", target->GetName()); + AddDefinitionEscaped(makefile, "_autogen_build_dir", + GetAutogenTargetBuildDir(target)); AddDefinitionEscaped(makefile, "_qt_version_major", qtMajorVersion); - AddDefinitionEscaped(makefile, "_sources", _sources); - AddDefinitionEscaped(makefile, "_headers", _headers); + AddDefinitionEscaped(makefile, "_sources", sources); + AddDefinitionEscaped(makefile, "_headers", headers); } - // Generate config file - std::string inputFile = cmSystemTools::GetCMakeRoot(); - inputFile += "/Modules/AutogenInfo.cmake.in"; - std::string outputFile = GetAutogenTargetFilesDir(target); - outputFile += "/AutogenInfo.cmake"; - - makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), false, true, - false); + // Generate info file + std::string infoFile = GetAutogenTargetFilesDir(target); + infoFile += "/AutogenInfo.cmake"; + { + std::string inf = cmSystemTools::GetCMakeRoot(); + inf += "/Modules/AutogenInfo.cmake.in"; + makefile->ConfigureFile(inf.c_str(), infoFile.c_str(), false, true, false); + } - // Append custom config definitions to info file - if (!configMocDefines.empty() || !configMocIncludes.empty() || - !configUicOptions.empty()) { + // Append custom definitions to info file on demand + if (!configSuffix.empty() || !configMocDefines.empty() || + !configMocIncludes.empty() || !configUicOptions.empty()) { // Ensure we have write permission in case .in was read-only. mode_t perm = 0; @@ -946,46 +1039,49 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( #else mode_t mode_write = S_IWUSR; #endif - cmSystemTools::GetPermissions(outputFile, perm); + cmSystemTools::GetPermissions(infoFile, perm); if (!(perm & mode_write)) { - cmSystemTools::SetPermissions(outputFile, perm | mode_write); + cmSystemTools::SetPermissions(infoFile, perm | mode_write); } - cmsys::ofstream infoFile(outputFile.c_str(), std::ios::app); - if (!infoFile) { - std::string error = "Internal CMake error when trying to open file: "; - error += outputFile; - error += " for writing."; - cmSystemTools::Error(error.c_str()); - } else { - infoFile << "# Configuration specific options\n"; - if (!configMocDefines.empty()) { - for (std::map<std::string, std::string>::iterator - it = configMocDefines.begin(), - end = configMocDefines.end(); - it != end; ++it) { - infoFile << "set(AM_MOC_DEFINITIONS_" << it->first << " " - << it->second << ")\n"; - } + // Open and write file + cmsys::ofstream ofs(infoFile.c_str(), std::ios::app); + if (ofs) { + ofs << "# Configuration specific options\n"; + for (std::map<std::string, std::string>::iterator + it = configSuffix.begin(), + end = configSuffix.end(); + it != end; ++it) { + ofs << "set(AM_CONFIG_SUFFIX_" << it->first << " " << it->second + << ")\n"; } - if (!configMocIncludes.empty()) { - for (std::map<std::string, std::string>::iterator - it = configMocIncludes.begin(), - end = configMocIncludes.end(); - it != end; ++it) { - infoFile << "set(AM_MOC_INCLUDES_" << it->first << " " << it->second - << ")\n"; - } + for (std::map<std::string, std::string>::iterator + it = configMocDefines.begin(), + end = configMocDefines.end(); + it != end; ++it) { + ofs << "set(AM_MOC_DEFINITIONS_" << it->first << " " << it->second + << ")\n"; } - if (!configUicOptions.empty()) { - for (std::map<std::string, std::string>::iterator - it = configUicOptions.begin(), - end = configUicOptions.end(); - it != end; ++it) { - infoFile << "set(AM_UIC_TARGET_OPTIONS_" << it->first << " " - << it->second << ")\n"; - } + for (std::map<std::string, std::string>::iterator + it = configMocIncludes.begin(), + end = configMocIncludes.end(); + it != end; ++it) { + ofs << "set(AM_MOC_INCLUDES_" << it->first << " " << it->second + << ")\n"; + } + for (std::map<std::string, std::string>::iterator + it = configUicOptions.begin(), + end = configUicOptions.end(); + it != end; ++it) { + ofs << "set(AM_UIC_TARGET_OPTIONS_" << it->first << " " << it->second + << ")\n"; } + } else { + // File open error + std::string error = "Internal CMake error when trying to open file: "; + error += cmQtAutoGeneratorCommon::Quoted(infoFile); + error += " for writing."; + cmSystemTools::Error(error.c_str()); } } } diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index d40e809..27e4928 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -78,8 +78,8 @@ static void InfoGet(cmMakefile* makefile, const char* key, cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list); } -static void InfoGet(cmMakefile* makefile, const char* key, - const std::string& config, std::vector<std::string>& list) +static void InfoGetConfig(cmMakefile* makefile, const char* key, + const std::string& config, std::string& value) { const char* valueConf = CM_NULLPTR; { @@ -93,7 +93,16 @@ static void InfoGet(cmMakefile* makefile, const char* key, if (valueConf == CM_NULLPTR) { valueConf = makefile->GetSafeDefinition(key); } - cmSystemTools::ExpandListArgument(valueConf, list); + value = valueConf; +} + +static void InfoGetConfig(cmMakefile* makefile, const char* key, + const std::string& config, + std::vector<std::string>& list) +{ + std::string value; + InfoGetConfig(makefile, key, config, value); + cmSystemTools::ExpandListArgument(value, list); } inline static bool SettingsMatch(cmMakefile* makefile, const char* key, @@ -270,6 +279,7 @@ cmQtAutoGenerators::cmQtAutoGenerators() } } + // Moc macro filters this->MocMacroFilters[0].first = "Q_OBJECT"; this->MocMacroFilters[0].second.compile("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); this->MocMacroFilters[1].first = "Q_GADGET"; @@ -358,12 +368,13 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( { this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory); cmSystemTools::ConvertToUnixSlashes(this->SettingsFile); - this->SettingsFile += "/AutogenOldSettings.cmake"; + this->SettingsFile += "/AutogenOldSettings"; + this->SettingsFile += this->ConfigSuffix; + this->SettingsFile += ".cmake"; } - // - Target names - InfoGet(makefile, "AM_TARGET_NAME", this->AutogenTargetName); - InfoGet(makefile, "AM_ORIGIN_TARGET_NAME", this->OriginTargetName); + // -- Meta + InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix); // - Files and directories InfoGet(makefile, "AM_CMAKE_SOURCE_DIR", this->ProjectSourceDir); @@ -372,6 +383,11 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( InfoGet(makefile, "AM_CMAKE_CURRENT_BINARY_DIR", this->CurrentBinaryDir); InfoGet(makefile, "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE", this->IncludeProjectDirsBefore); + InfoGet(makefile, "AM_BUILD_DIR", this->AutogenBuildDir); + if (this->AutogenBuildDir.empty()) { + this->LogError("AutoGen: Error: Missing autogen build directory "); + return false; + } InfoGet(makefile, "AM_SOURCES", this->Sources); InfoGet(makefile, "AM_HEADERS", this->Headers); @@ -395,7 +411,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( // - Moc if (this->MocEnabled()) { InfoGet(makefile, "AM_MOC_SKIP", this->MocSkipList); - InfoGet(makefile, "AM_MOC_DEFINITIONS", config, this->MocDefinitions); + InfoGetConfig(makefile, "AM_MOC_DEFINITIONS", config, + this->MocDefinitions); #ifdef _WIN32 { const std::string win32("WIN32"); @@ -404,7 +421,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( } } #endif - InfoGet(makefile, "AM_MOC_INCLUDES", config, this->MocIncludePaths); + InfoGetConfig(makefile, "AM_MOC_INCLUDES", config, this->MocIncludePaths); InfoGet(makefile, "AM_MOC_OPTIONS", this->MocOptions); InfoGet(makefile, "AM_MOC_RELAXED_MODE", this->MocRelaxedMode); { @@ -439,7 +456,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( if (this->UicEnabled()) { InfoGet(makefile, "AM_UIC_SKIP", this->UicSkipList); InfoGet(makefile, "AM_UIC_SEARCH_PATHS", this->UicSearchPaths); - InfoGet(makefile, "AM_UIC_TARGET_OPTIONS", config, this->UicTargetOptions); + InfoGetConfig(makefile, "AM_UIC_TARGET_OPTIONS", config, + this->UicTargetOptions); { std::vector<std::string> uicFilesVec; std::vector<std::string> uicOptionsVec; @@ -615,18 +633,23 @@ bool cmQtAutoGenerators::SettingsFileWrite() void cmQtAutoGenerators::Init(cmMakefile* makefile) { - this->AutogenBuildSubDir = this->AutogenTargetName; - this->AutogenBuildSubDir += "/"; - - this->MocCppFilenameRel = this->AutogenBuildSubDir; - this->MocCppFilenameRel += "moc_compilation.cpp"; - - this->MocCppFilenameAbs = this->CurrentBinaryDir + this->MocCppFilenameRel; + // Mocs compilation file + this->MocCompFileRel = "mocs_compilation"; + this->MocCompFileRel += this->ConfigSuffix; + this->MocCompFileRel += ".cpp"; + this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath( + this->AutogenBuildDir, this->MocCompFileRel); + + // Mocs include directory + this->AutogenIncludeDir = "include"; + this->AutogenIncludeDir += this->ConfigSuffix; + this->AutogenIncludeDir += "/"; // Moc predefs file if (!this->MocPredefsCmd.empty()) { - this->MocPredefsFileRel = this->AutogenBuildSubDir + "moc_predefs.h"; - this->MocPredefsFileAbs = this->CurrentBinaryDir + this->MocPredefsFileRel; + this->MocPredefsFileRel = "moc_predefs.h"; + this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath( + this->AutogenBuildDir, this->MocPredefsFileRel); } // Init file path checksum generator @@ -699,10 +722,10 @@ bool cmQtAutoGenerators::RunAutogen() // the program goes through all .cpp files to see which moc files are // included. It is not really interesting how the moc file is named, but // what file the moc is created from. Once a moc is included the same moc - // may not be included in the moc_compilation.cpp file anymore. OTOH if - // there's a header containing Q_OBJECT where no corresponding moc file - // is included anywhere a moc_<filename>.cpp file is created and included - // in the moc_compilation.cpp file. + // may not be included in the mocs_compilation_$<CONFIG>.cpp file anymore. + // OTOH if there's a header containing Q_OBJECT where no corresponding + // moc file is included anywhere a moc_<filename>.cpp file is created and + // included in the mocs_compilation_$<CONFIG>.cpp file. // key = moc source filepath, value = moc output filepath std::map<std::string, std::string> mocsIncluded; @@ -1107,7 +1130,7 @@ void cmQtAutoGenerators::MocParseHeaderContent( if (this->MocRequired(contentText)) { // Register moc job mocsNotIncluded[absFilename] = - this->ChecksumedPath(absFilename, "moc_", ".cpp"); + this->ChecksumedPath(absFilename, "moc_", this->ConfigSuffix + ".cpp"); this->MocFindDepends(absFilename, contentText, mocDepends); } } @@ -1257,37 +1280,31 @@ bool cmQtAutoGenerators::MocGenerateAll( } // Generate moc files that are included by source files. - { - const std::string subDir = "include/"; - for (std::map<std::string, std::string>::const_iterator it = - mocsIncluded.begin(); - it != mocsIncluded.end(); ++it) { - if (!this->MocGenerateFile(it->first, it->second, subDir, mocDepends)) { - if (this->MocRunFailed) { - return false; - } + for (std::map<std::string, std::string>::const_iterator it = + mocsIncluded.begin(); + it != mocsIncluded.end(); ++it) { + if (!this->MocGenerateFile(it->first, it->second, mocDepends, true)) { + if (this->MocRunFailed) { + return false; } } } // Generate moc files that are _not_ included by source files. bool mocCompFileGenerated = false; - { - const std::string subDir; - for (std::map<std::string, std::string>::const_iterator it = - mocsNotIncluded.begin(); - it != mocsNotIncluded.end(); ++it) { - if (this->MocGenerateFile(it->first, it->second, subDir, mocDepends)) { - mocCompFileGenerated = true; - } else { - if (this->MocRunFailed) { - return false; - } + for (std::map<std::string, std::string>::const_iterator it = + mocsNotIncluded.begin(); + it != mocsNotIncluded.end(); ++it) { + if (this->MocGenerateFile(it->first, it->second, mocDepends, false)) { + mocCompFileGenerated = true; + } else { + if (this->MocRunFailed) { + return false; } } } - // Compose moc_compilation.cpp content + // Compose mocs compilation file content std::string automocSource; { std::ostringstream ost; @@ -1306,18 +1323,18 @@ bool cmQtAutoGenerators::MocGenerateAll( automocSource = ost.str(); } - if (this->FileDiffers(this->MocCppFilenameAbs, automocSource)) { - // Actually write moc_compilation.cpp - this->LogBold("Generating MOC compilation " + this->MocCppFilenameRel); - if (!this->FileWrite("AutoMoc", this->MocCppFilenameAbs, automocSource)) { + if (this->FileDiffers(this->MocCompFileAbs, automocSource)) { + // Actually write mocs compilation file + this->LogBold("Generating MOC compilation " + this->MocCompFileRel); + if (!this->FileWrite("AutoMoc", this->MocCompFileAbs, automocSource)) { return false; } } else if (mocCompFileGenerated) { - // Only touch moc_compilation.cpp + // Only touch mocs compilation file if (this->Verbose) { - this->LogInfo("Touching MOC compilation " + this->MocCppFilenameRel); + this->LogInfo("Touching MOC compilation " + this->MocCompFileRel); } - cmSystemTools::Touch(this->MocCppFilenameAbs, false); + cmSystemTools::Touch(this->MocCompFileAbs, false); } return true; @@ -1328,15 +1345,16 @@ bool cmQtAutoGenerators::MocGenerateAll( */ bool cmQtAutoGenerators::MocGenerateFile( const std::string& sourceFile, const std::string& mocFileName, - const std::string& subDir, - const std::map<std::string, std::set<std::string> >& mocDepends) + const std::map<std::string, std::set<std::string> >& mocDepends, + bool included) { bool mocGenerated = false; bool generateMoc = this->MocSettingsChanged || this->MocPredefsChanged; const std::string mocFileRel = - this->AutogenBuildSubDir + subDir + mocFileName; - const std::string mocFileAbs = this->CurrentBinaryDir + mocFileRel; + included ? (this->AutogenIncludeDir + mocFileName) : mocFileName; + const std::string mocFileAbs = + cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, mocFileRel); if (!generateMoc) { // Test if the source file is newer that the build file @@ -1524,9 +1542,9 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, bool uicGenerated = false; bool generateUic = this->UicSettingsChanged; - const std::string uicFileRel = - this->AutogenBuildSubDir + "include/" + uiOutputFile; - const std::string uicFileAbs = this->CurrentBinaryDir + uicFileRel; + const std::string uicFileRel = this->AutogenIncludeDir + uiOutputFile; + const std::string uicFileAbs = + cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, uicFileRel); if (!generateUic) { // Test if the source file is newer that the build file @@ -1590,12 +1608,17 @@ bool cmQtAutoGenerators::RccGenerateAll() // generate single map with input / output names std::map<std::string, std::string> qrcGenMap; - for (std::vector<std::string>::const_iterator si = this->RccSources.begin(); - si != this->RccSources.end(); ++si) { - const std::string ext = cmsys::SystemTools::GetFilenameLastExtension(*si); - if (ext == ".qrc") { - qrcGenMap[*si] = - this->AutogenBuildSubDir + this->ChecksumedPath(*si, "qrc_", ".cpp"); + { + const std::string qrcPrefix = "qrc_"; + const std::string qrcSuffix = this->ConfigSuffix + ".cpp"; + for (std::vector<std::string>::const_iterator si = + this->RccSources.begin(); + si != this->RccSources.end(); ++si) { + const std::string ext = + cmsys::SystemTools::GetFilenameLastExtension(*si); + if (ext == ".qrc") { + qrcGenMap[*si] = this->ChecksumedPath(*si, qrcPrefix, qrcSuffix); + } } } @@ -1636,7 +1659,8 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, bool rccGenerated = false; bool generateRcc = this->RccSettingsChanged; - const std::string rccBuildFile = this->CurrentBinaryDir + rccOutputFile; + const std::string rccBuildFile = + cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, rccOutputFile); if (!generateRcc) { // Test if the resources list file is newer than build file @@ -1827,9 +1851,9 @@ bool cmQtAutoGenerators::NameCollisionTest( * @brief Generates a file path based on the checksum of the source file path * @return The path */ -std::string cmQtAutoGenerators::ChecksumedPath(const std::string& sourceFile, - const char* basePrefix, - const char* baseSuffix) const +std::string cmQtAutoGenerators::ChecksumedPath( + const std::string& sourceFile, const std::string& basePrefix, + const std::string& baseSuffix) const { std::string res = FPathChecksum.getPart(sourceFile); res += "/"; diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 987110f..b525364 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -107,8 +107,8 @@ private: const std::map<std::string, std::set<std::string> >& mocDepends); bool MocGenerateFile( const std::string& sourceFile, const std::string& mocFileName, - const std::string& subDir, - const std::map<std::string, std::set<std::string> >& mocDepends); + const std::map<std::string, std::set<std::string> >& mocDepends, + bool included); // -- Uic file generation bool UicFindIncludedFile(std::string& absFile, const std::string& sourceFile, @@ -139,8 +139,8 @@ private: const std::map<std::string, std::string>& genFiles, std::multimap<std::string, std::string>& collisions) const; std::string ChecksumedPath(const std::string& sourceFile, - const char* basePrefix, - const char* baseSuffix) const; + const std::string& basePrefix, + const std::string& baseSuffix) const; bool MakeParentDirectory(const char* logPrefix, const std::string& filename) const; bool FileDiffers(const std::string& filename, const std::string& content); @@ -157,15 +157,15 @@ private: bool MocFindIncludedFile(std::string& absFile, const std::string& sourceFile, const std::string& includeString) const; - // -- Target names - std::string OriginTargetName; - std::string AutogenTargetName; + // -- Meta + std::string ConfigSuffix; // -- Directories std::string ProjectSourceDir; std::string ProjectBinaryDir; std::string CurrentSourceDir; std::string CurrentBinaryDir; - std::string AutogenBuildSubDir; + std::string AutogenBuildDir; + std::string AutogenIncludeDir; // -- Qt environment std::string QtMajorVersion; std::string MocExecutable; @@ -189,8 +189,8 @@ private: bool MocPredefsChanged; bool MocRelaxedMode; bool MocRunFailed; - std::string MocCppFilenameRel; - std::string MocCppFilenameAbs; + std::string MocCompFileRel; + std::string MocCompFileAbs; std::string MocPredefsFileRel; std::string MocPredefsFileAbs; std::vector<std::string> MocSkipList; diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx index 5a52927..1db8441 100644 --- a/Source/cmRemoveCommand.cxx +++ b/Source/cmRemoveCommand.cxx @@ -15,7 +15,7 @@ bool cmRemoveCommand::InitialPass(std::vector<std::string> const& args, return true; } - const char* variable = args[0].c_str(); // VAR is always first + std::string const& variable = args[0]; // VAR is always first // get the old value const char* cacheValue = this->Makefile->GetDefinition(variable); diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx index 60c198a..b57f62a 100644 --- a/Source/cmSetPropertyCommand.cxx +++ b/Source/cmSetPropertyCommand.cxx @@ -138,7 +138,7 @@ bool cmSetPropertyCommand::HandleGlobalMode() // Set or append the property. cmake* cm = this->Makefile->GetCMakeInstance(); - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -188,7 +188,7 @@ bool cmSetPropertyCommand::HandleDirectoryMode() } // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -229,7 +229,7 @@ bool cmSetPropertyCommand::HandleTargetMode() bool cmSetPropertyCommand::HandleTarget(cmTarget* target) { // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -268,7 +268,7 @@ bool cmSetPropertyCommand::HandleSourceMode() bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf) { // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -316,7 +316,7 @@ bool cmSetPropertyCommand::HandleTestMode() bool cmSetPropertyCommand::HandleTest(cmTest* test) { // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); if (this->Remove) { value = CM_NULLPTR; @@ -383,7 +383,7 @@ bool cmSetPropertyCommand::HandleCacheMode() bool cmSetPropertyCommand::HandleCacheEntry(std::string const& cacheKey) { // Set or append the property. - const char* name = this->PropertyName.c_str(); + std::string const& name = this->PropertyName; const char* value = this->PropertyValue.c_str(); cmState* state = this->Makefile->GetState(); if (this->Remove) { diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index d6907e3..7a097ba 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -128,7 +128,7 @@ bool cmStringCommand::HandleToUpperLowerCommand( return false; } - std::string outvar = args[2]; + std::string const& outvar = args[2]; std::string output; if (toUpper) { @@ -149,7 +149,7 @@ bool cmStringCommand::HandleAsciiCommand(std::vector<std::string> const& args) return false; } std::string::size_type cc; - std::string outvar = args[args.size() - 1]; + std::string const& outvar = args[args.size() - 1]; std::string output; for (cc = 1; cc < args.size() - 1; cc++) { int ch = atoi(args[cc].c_str()); @@ -212,7 +212,7 @@ bool cmStringCommand::HandleRegexCommand(std::vector<std::string> const& args) this->SetError("sub-command REGEX requires a mode to be specified."); return false; } - std::string mode = args[1]; + std::string const& mode = args[1]; if (mode == "MATCH") { if (args.size() < 5) { this->SetError("sub-command REGEX, mode MATCH needs " @@ -247,8 +247,8 @@ bool cmStringCommand::RegexMatch(std::vector<std::string> const& args) { //"STRING(REGEX MATCH <regular_expression> <output variable> // <input> [<input>...])\n"; - std::string regex = args[2]; - std::string outvar = args[3]; + std::string const& regex = args[2]; + std::string const& outvar = args[3]; this->Makefile->ClearMatches(); // Compile the regular expression. @@ -288,8 +288,8 @@ bool cmStringCommand::RegexMatchAll(std::vector<std::string> const& args) { //"STRING(REGEX MATCHALL <regular_expression> <output variable> <input> // [<input>...])\n"; - std::string regex = args[2]; - std::string outvar = args[3]; + std::string const& regex = args[2]; + std::string const& outvar = args[3]; this->Makefile->ClearMatches(); // Compile the regular expression. @@ -334,9 +334,9 @@ bool cmStringCommand::RegexReplace(std::vector<std::string> const& args) { //"STRING(REGEX REPLACE <regular_expression> <replace_expression> // <output variable> <input> [<input>...])\n" - std::string regex = args[2]; - std::string replace = args[3]; - std::string outvar = args[4]; + std::string const& regex = args[2]; + std::string const& replace = args[3]; + std::string const& outvar = args[4]; // Pull apart the replace expression to find the escaped [0-9] values. std::vector<RegexReplacement> replacement; @@ -502,7 +502,7 @@ bool cmStringCommand::HandleCompareCommand( this->SetError("sub-command COMPARE requires a mode to be specified."); return false; } - std::string mode = args[1]; + std::string const& mode = args[1]; if ((mode == "EQUAL") || (mode == "NOTEQUAL") || (mode == "LESS") || (mode == "LESS_EQUAL") || (mode == "GREATER") || (mode == "GREATER_EQUAL")) { diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 8978e18..dc7034e 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -196,7 +196,6 @@ void cmSystemTools::ExpandRegistryValues(std::string& source, while (regEntry.find(source)) { // the arguments are the second match std::string key = regEntry.match(1); - std::string val; std::string reg = "["; reg += key + "]"; cmSystemTools::ReplaceString(source, reg.c_str(), "/registry"); @@ -348,12 +347,12 @@ bool cmSystemTools::IsInternallyOn(const char* val) if (!val) { return false; } - std::basic_string<char> v = val; + std::string v = val; if (v.size() > 4) { return false; } - for (std::basic_string<char>::iterator c = v.begin(); c != v.end(); c++) { + for (std::string::iterator c = v.begin(); c != v.end(); c++) { *c = static_cast<char>(toupper(*c)); } return v == "I_ON"; @@ -368,7 +367,7 @@ bool cmSystemTools::IsOn(const char* val) if (len > 4) { return false; } - std::basic_string<char> v(val, len); + std::string v(val, len); static std::set<std::string> onValues; if (onValues.empty()) { @@ -378,7 +377,7 @@ bool cmSystemTools::IsOn(const char* val) onValues.insert("TRUE"); onValues.insert("Y"); } - for (std::basic_string<char>::iterator c = v.begin(); c != v.end(); c++) { + for (std::string::iterator c = v.begin(); c != v.end(); c++) { *c = static_cast<char>(toupper(*c)); } return (onValues.count(v) > 0); @@ -413,8 +412,8 @@ bool cmSystemTools::IsOff(const char* val) offValues.insert("IGNORE"); } // Try and avoid toupper(). - std::basic_string<char> v(val, len); - for (std::basic_string<char>::iterator c = v.begin(); c != v.end(); c++) { + std::string v(val, len); + for (std::string::iterator c = v.begin(); c != v.end(); c++) { *c = static_cast<char>(toupper(*c)); } return (offValues.count(v) > 0); diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index 9a5c1da..45fe430 100644 --- a/Source/cmTargetPropCommandBase.cxx +++ b/Source/cmTargetPropCommandBase.cxx @@ -78,7 +78,7 @@ bool cmTargetPropCommandBase::ProcessContentArgs( std::vector<std::string> const& args, unsigned int& argIndex, bool prepend, bool system) { - const std::string scope = args[argIndex]; + std::string const& scope = args[argIndex]; if (scope != "PUBLIC" && scope != "PRIVATE" && scope != "INTERFACE") { this->SetError("called with invalid arguments"); diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx index 37d8bfb..eabd7ef 100644 --- a/Source/cmUtilitySourceCommand.cxx +++ b/Source/cmUtilitySourceCommand.cxx @@ -23,7 +23,7 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, std::vector<std::string>::const_iterator arg = args.begin(); // The first argument is the cache entry name. - std::string cacheEntry = *arg++; + std::string const& cacheEntry = *arg++; const char* cacheValue = this->Makefile->GetDefinition(cacheEntry); // If it exists already and appears up to date then we are done. If // the string contains "(IntDir)" but that is not the @@ -57,11 +57,11 @@ bool cmUtilitySourceCommand::InitialPass(std::vector<std::string> const& args, // The second argument is the utility's executable name, which will be // needed later. - std::string utilityName = *arg++; + std::string const& utilityName = *arg++; // The third argument specifies the relative directory of the source // of the utility. - std::string relativeSource = *arg++; + std::string const& relativeSource = *arg++; std::string utilitySource = this->Makefile->GetCurrentSourceDirectory(); utilitySource = utilitySource + "/" + relativeSource; diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx index 10b0a88..06ca53c 100644 --- a/Source/cmVariableRequiresCommand.cxx +++ b/Source/cmVariableRequiresCommand.cxx @@ -17,11 +17,11 @@ bool cmVariableRequiresCommand::InitialPass( return false; } - std::string testVariable = args[0]; + std::string const& testVariable = args[0]; if (!this->Makefile->IsOn(testVariable)) { return true; } - std::string resultVariable = args[1]; + std::string const& resultVariable = args[1]; bool requirementsMet = true; std::string notSet; bool hasAdvanced = false; diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx index 90b0b28..281850e 100644 --- a/Source/cmVariableWatchCommand.cxx +++ b/Source/cmVariableWatchCommand.cxx @@ -106,7 +106,7 @@ bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args, this->SetError("must be called with at least one argument."); return false; } - std::string variable = args[0]; + std::string const& variable = args[0]; std::string command; if (args.size() > 1) { command = args[1]; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index eef6f37..e174f13 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2074,15 +2074,15 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() return; } - this->WriteString("<PropertyGroup>\n", 2); + this->WriteString("<PropertyGroup>\n", 1); this->WriteString("<_ProjectFileVersion>10.0.20506.1" "</_ProjectFileVersion>\n", - 3); + 2); for (std::vector<std::string>::const_iterator config = this->Configurations.begin(); config != this->Configurations.end(); ++config) { if (ttype >= cmStateEnums::UTILITY) { - this->WritePlatformConfigTag("IntDir", config->c_str(), 3); + this->WritePlatformConfigTag("IntDir", config->c_str(), 2); *this->BuildFileStream << "$(Platform)\\$(Configuration)\\$(ProjectName)\\" << "</IntDir>\n"; @@ -2105,24 +2105,24 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() this->ConvertToWindowsSlash(intermediateDir); this->ConvertToWindowsSlash(outDir); - this->WritePlatformConfigTag("OutDir", config->c_str(), 3); + this->WritePlatformConfigTag("OutDir", config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(outDir) << "</OutDir>\n"; - this->WritePlatformConfigTag("IntDir", config->c_str(), 3); + this->WritePlatformConfigTag("IntDir", config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(intermediateDir) << "</IntDir>\n"; if (const char* workingDir = this->GeneratorTarget->GetProperty( "VS_DEBUGGER_WORKING_DIRECTORY")) { this->WritePlatformConfigTag("LocalDebuggerWorkingDirectory", - config->c_str(), 3); + config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(workingDir) << "</LocalDebuggerWorkingDirectory>\n"; } std::string name = cmSystemTools::GetFilenameWithoutLastExtension(targetNameFull); - this->WritePlatformConfigTag("TargetName", config->c_str(), 3); + this->WritePlatformConfigTag("TargetName", config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(name) << "</TargetName>\n"; std::string ext = @@ -2132,13 +2132,13 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions() // A single "." appears to be treated as an empty extension. ext = "."; } - this->WritePlatformConfigTag("TargetExt", config->c_str(), 3); + this->WritePlatformConfigTag("TargetExt", config->c_str(), 2); *this->BuildFileStream << cmVS10EscapeXML(ext) << "</TargetExt>\n"; this->OutputLinkIncremental(*config); } } - this->WriteString("</PropertyGroup>\n", 2); + this->WriteString("</PropertyGroup>\n", 1); } void cmVisualStudio10TargetGenerator::OutputLinkIncremental( @@ -2159,13 +2159,13 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental( Options& linkOptions = *(this->LinkOptions[configName]); const char* incremental = linkOptions.GetFlag("LinkIncremental"); - this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3); + this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 2); *this->BuildFileStream << (incremental ? incremental : "true") << "</LinkIncremental>\n"; linkOptions.RemoveFlag("LinkIncremental"); const char* manifest = linkOptions.GetFlag("GenerateManifest"); - this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3); + this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 2); *this->BuildFileStream << (manifest ? manifest : "true") << "</GenerateManifest>\n"; linkOptions.RemoveFlag("GenerateManifest"); @@ -2176,7 +2176,7 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental( for (const char** f = flags; *f; ++f) { const char* flag = *f; if (const char* value = linkOptions.GetFlag(flag)) { - this->WritePlatformConfigTag(flag, configName.c_str(), 3); + this->WritePlatformConfigTag(flag, configName.c_str(), 2); *this->BuildFileStream << value << "</" << flag << ">\n"; linkOptions.RemoveFlag(flag); } diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx index f569e80..fc5fd21 100644 --- a/Source/cmWriteFileCommand.cxx +++ b/Source/cmWriteFileCommand.cxx @@ -21,7 +21,7 @@ bool cmWriteFileCommand::InitialPass(std::vector<std::string> const& args, std::string message; std::vector<std::string>::const_iterator i = args.begin(); - std::string fileName = *i; + std::string const& fileName = *i; bool overwrite = true; i++; diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx index fcd1e48..cf55741 100644 --- a/Source/cm_codecvt.cxx +++ b/Source/cm_codecvt.cxx @@ -1,18 +1,23 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cm_codecvt.hxx" -#include <limits> #if defined(_WIN32) +#include <assert.h> +#include <string.h> #include <windows.h> #undef max #include "cmsys/Encoding.hxx" #endif +#if defined(_WIN32) +/* Number of leading ones before a zero in the byte (see cm_utf8.c). */ +extern "C" unsigned char const cm_utf8_ones[256]; +#endif + codecvt::codecvt(Encoding e) - : m_lastState(0) #if defined(_WIN32) - , m_codepage(0) + : m_codepage(0) #endif { switch (e) { @@ -45,76 +50,68 @@ std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from, const char*& from_next, char* to, char* to_end, char*& to_next) const { + from_next = from; + to_next = to; if (m_noconv) { - return noconv; + return std::codecvt_base::noconv; } - std::codecvt_base::result res = error; #if defined(_WIN32) - from_next = from; - to_next = to; - bool convert = true; - size_t count = from_end - from; - const char* data = from; - unsigned int& stateId = reinterpret_cast<unsigned int&>(state); - if (count == 0) { - return codecvt::ok; - } else if (count == 1) { - if (stateId == 0) { - // decode first byte for UTF-8 - if ((*from & 0xF8) == 0xF0 || // 1111 0xxx; 4 bytes for codepoint - (*from & 0xF0) == 0xE0 || // 1110 xxxx; 3 bytes for codepoint - (*from & 0xE0) == 0xC0) // 110x xxxx; 2 bytes for codepoint - { - stateId = findStateId(); - codecvt::State& s = m_states.at(stateId - 1); - s.bytes[0] = *from; - convert = false; - if ((*from & 0xF8) == 0xF0) { - s.totalBytes = 4; - } else if ((*from & 0xF0) == 0xE0) { - s.totalBytes = 3; - } else if ((*from & 0xE0) == 0xC0) { - s.totalBytes = 2; - } - s.bytesLeft = s.totalBytes - 1; - }; - // else 1 byte for codepoint - } else { - codecvt::State& s = m_states.at(stateId - 1); - s.bytes[s.totalBytes - s.bytesLeft] = *from; - s.bytesLeft--; - data = s.bytes; - count = s.totalBytes - s.bytesLeft; - if ((*from & 0xC0) == 0x80) { // 10xx xxxx - convert = s.bytesLeft == 0; - } else { - // invalid multi-byte - convert = true; - } - if (convert) { - s.used = false; - if (stateId == m_lastState) { - m_lastState--; - } - stateId = 0; - } + // Use a const view of the state because we should not modify it until we + // have fully processed and consume a byte (with sufficient space in the + // output buffer). We call helpers to re-cast and modify the state + State const& lstate = reinterpret_cast<State&>(state); + + while (from_next != from_end) { + // Count leading ones in the bits of the next byte. + unsigned char const ones = + cm_utf8_ones[static_cast<unsigned char>(*from_next)]; + + if (ones != 1 && lstate.buffered != 0) { + // We have a buffered partial codepoint that we never completed. + return std::codecvt_base::error; + } else if (ones == 1 && lstate.buffered == 0) { + // This is a continuation of a codepoint that never started. + return std::codecvt_base::error; + } + + // Compute the number of bytes in the current codepoint. + int need = 0; + switch (ones) { + case 0: // 0xxx xxxx: new codepoint of size 1 + need = 1; + break; + case 1: // 10xx xxxx: continues a codepoint + assert(lstate.size != 0); + need = lstate.size; + break; + case 2: // 110x xxxx: new codepoint of size 2 + need = 2; + break; + case 3: // 1110 xxxx: new codepoint of size 3 + need = 3; + break; + case 4: // 1111 0xxx: new codepoint of size 4 + need = 4; + break; + default: // invalid byte + return std::codecvt_base::error; } - if (convert) { - std::wstring wide = cmsys::Encoding::ToWide(std::string(data, count)); - int r = WideCharToMultiByte(m_codepage, 0, wide.c_str(), - static_cast<int>(wide.size()), to, - to_end - to, NULL, NULL); - if (r > 0) { - from_next = from_end; - to_next = to + r; - res = ok; + assert(need > 0); + + if (lstate.buffered + 1 == need) { + // This byte completes a codepoint. + std::codecvt_base::result decode_result = + this->Decode(state, need, from_next, to_next, to_end); + if (decode_result != std::codecvt_base::ok) { + return decode_result; } } else { - res = partial; - from_next = from_end; - to_next = to; + // This byte does not complete a codepoint. + this->BufferPartial(state, need, from_next); } } + + return std::codecvt_base::ok; #else static_cast<void>(state); static_cast<void>(from); @@ -123,46 +120,118 @@ std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from, static_cast<void>(to); static_cast<void>(to_end); static_cast<void>(to_next); - res = codecvt::noconv; + return std::codecvt_base::noconv; #endif - return res; }; std::codecvt_base::result codecvt::do_unshift(mbstate_t& state, char* to, char* to_end, char*& to_next) const { - std::codecvt_base::result res = error; to_next = to; + if (m_noconv) { + return std::codecvt_base::noconv; + } #if defined(_WIN32) - unsigned int& stateId = reinterpret_cast<unsigned int&>(state); - if (stateId > 0) { - codecvt::State& s = m_states.at(stateId - 1); - s.used = false; - if (stateId == m_lastState) { - m_lastState--; - } - stateId = 0; - std::wstring wide = cmsys::Encoding::ToWide( - std::string(s.bytes, s.totalBytes - s.bytesLeft)); - int r = WideCharToMultiByte(m_codepage, 0, wide.c_str(), - static_cast<int>(wide.size()), to, to_end - to, - NULL, NULL); - if (r > 0) { - to_next = to + r; - res = ok; - } - } else { - res = ok; + State& lstate = reinterpret_cast<State&>(state); + if (lstate.buffered != 0) { + return this->DecodePartial(state, to_next, to_end); } + return std::codecvt_base::ok; #else static_cast<void>(state); static_cast<void>(to_end); - res = ok; + return std::codecvt_base::ok; #endif - return res; }; +#if defined(_WIN32) +std::codecvt_base::result codecvt::Decode(mbstate_t& state, int size, + const char*& from_next, + char*& to_next, char* to_end) const +{ + State& lstate = reinterpret_cast<State&>(state); + + // Collect all the bytes for this codepoint. + char buf[4]; + memcpy(buf, lstate.partial, lstate.buffered); + buf[lstate.buffered] = *from_next; + + // Convert the encoding. + wchar_t wbuf[2]; + int wlen = + MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, buf, size, wbuf, 2); + if (wlen <= 0) { + return std::codecvt_base::error; + } + + int tlen = WideCharToMultiByte(m_codepage, 0, wbuf, wlen, to_next, + to_end - to_next, NULL, NULL); + if (tlen <= 0) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + return std::codecvt_base::partial; + } + return std::codecvt_base::error; + } + + // Move past the now-consumed byte in the input buffer. + ++from_next; + + // Move past the converted codepoint in the output buffer. + to_next += tlen; + + // Re-initialize the state for the next codepoint to start. + lstate = State(); + + return std::codecvt_base::ok; +} + +std::codecvt_base::result codecvt::DecodePartial(mbstate_t& state, + char*& to_next, + char* to_end) const +{ + State& lstate = reinterpret_cast<State&>(state); + + // Try converting the partial codepoint. + wchar_t wbuf[2]; + int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, lstate.partial, + lstate.buffered, wbuf, 2); + if (wlen <= 0) { + return std::codecvt_base::error; + } + + int tlen = WideCharToMultiByte(m_codepage, 0, wbuf, wlen, to_next, + to_end - to_next, NULL, NULL); + if (tlen <= 0) { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + return std::codecvt_base::partial; + } + return std::codecvt_base::error; + } + + // Move past the converted codepoint in the output buffer. + to_next += tlen; + + // Re-initialize the state for the next codepoint to start. + lstate = State(); + + return std::codecvt_base::ok; +} + +void codecvt::BufferPartial(mbstate_t& state, int size, + const char*& from_next) const +{ + State& lstate = reinterpret_cast<State&>(state); + + // Save the byte in our buffer for later. + lstate.partial[lstate.buffered++] = *from_next; + lstate.size = size; + + // Move past the now-consumed byte in the input buffer. + ++from_next; +} +#endif + int codecvt::do_max_length() const throw() { return 4; @@ -172,44 +241,3 @@ int codecvt::do_encoding() const throw() { return 0; }; - -unsigned int codecvt::findStateId() const -{ - unsigned int stateId = 0; - bool add = false; - const unsigned int maxSize = std::numeric_limits<unsigned int>::max(); - if (m_lastState >= maxSize) { - m_lastState = 0; - } - if (m_states.size() <= m_lastState) { - add = true; - } else { - unsigned int i = m_lastState; - while (i < maxSize) { - codecvt::State& s = m_states.at(i); - i++; - if (!s.used) { - m_lastState = i; - stateId = m_lastState; - s.used = true; - s.totalBytes = 0; - s.bytesLeft = 0; - break; - } - if (i >= m_states.size()) { - i = 0; - } - if (i == m_lastState) { - add = true; - break; - } - } - }; - if (add) { - codecvt::State s = { true, 0, 0, { 0, 0, 0, 0 } }; - m_states.push_back(s); - m_lastState = (unsigned int)m_states.size(); - stateId = m_lastState; - } - return stateId; -}; diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx index b9b52ec..30c6d54 100644 --- a/Source/cm_codecvt.hxx +++ b/Source/cm_codecvt.hxx @@ -6,7 +6,6 @@ #include "cmConfigure.h" #include <locale> -#include <vector> #include <wchar.h> class codecvt : public std::codecvt<char, char, mbstate_t> @@ -35,21 +34,30 @@ protected: int do_encoding() const throw() CM_OVERRIDE; private: - typedef struct + // The mbstate_t argument to do_out and do_unshift is responsible + // for storing state between calls. We cannot control the type + // since we want to imbue on standard streams. However, we do + // know that it is a trivial type. Define our own type to overlay + // on it safely with no alignment requirements. + struct State { - bool used; - unsigned char totalBytes; - unsigned char bytesLeft; - char bytes[4]; - } State; + // Buffer bytes we have consumed from a partial codepoint. + char partial[3]; - unsigned int findStateId() const; + // Number of bytes we have buffered from a partial codepoint. + unsigned char buffered : 4; + + // Size of the current codepoint in bytes. + unsigned char size : 4; + }; bool m_noconv; - mutable std::vector<State> m_states; - mutable unsigned int m_lastState; #if defined(_WIN32) unsigned int m_codepage; + result Decode(mbstate_t& state, int need, const char*& from_next, + char*& to_next, char* to_end) const; + result DecodePartial(mbstate_t& state, char*& to_next, char* to_end) const; + void BufferPartial(mbstate_t& state, int need, const char*& from_next) const; #endif #endif diff --git a/Source/cm_utf8.c b/Source/cm_utf8.c index 6c49b52..52af4a6 100644 --- a/Source/cm_utf8.c +++ b/Source/cm_utf8.c @@ -15,7 +15,7 @@ */ /* Number of leading ones before a zero in the byte. */ -static unsigned char const cm_utf8_ones[256] = { +unsigned char const cm_utf8_ones[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 53e9ab0..6894393 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -301,7 +301,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args) { bool findPackageMode = false; for (unsigned int i = 1; i < args.size(); ++i) { - std::string arg = args[i]; + std::string const& arg = args[i]; if (arg.find("-D", 0) == 0) { std::string entry = arg.substr(2); if (entry.empty()) { @@ -617,7 +617,7 @@ void cmake::SetArgs(const std::vector<std::string>& args, bool haveToolset = false; bool havePlatform = false; for (unsigned int i = 1; i < args.size(); ++i) { - std::string arg = args[i]; + std::string const& arg = args[i]; if (arg.find("-H", 0) == 0) { directoriesSet = true; std::string path = arg.substr(2); @@ -2146,7 +2146,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args) // process the arguments bool writeToStdout = true; for (unsigned int i = 1; i < args.size(); ++i) { - std::string arg = args[i]; + std::string const& arg = args[i]; if (arg.find("-G", 0) == 0) { std::string value = arg.substr(2); if (value.empty()) { diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index dc267e7..9f2e8b7 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -663,7 +663,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) // Command to change directory and run a program. if (args[1] == "chdir" && args.size() >= 4) { - std::string directory = args[2]; + std::string const& directory = args[2]; if (!cmSystemTools::FileExists(directory.c_str())) { cmSystemTools::Error("Directory does not exist for chdir command: ", args[2].c_str()); @@ -883,8 +883,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) if (args[1] == "tar" && args.size() > 3) { const char* knownFormats[] = { "7zip", "gnutar", "pax", "paxr", "zip" }; - std::string flags = args[2]; - std::string outFile = args[3]; + std::string const& flags = args[2]; + std::string const& outFile = args[3]; std::vector<std::string> files; std::string mtime; std::string format; @@ -1077,9 +1077,9 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string>& args) int cmcmd::SymlinkLibrary(std::vector<std::string>& args) { int result = 0; - std::string realName = args[2]; - std::string soName = args[3]; - std::string name = args[4]; + std::string const& realName = args[2]; + std::string const& soName = args[3]; + std::string const& name = args[4]; if (soName != realName) { if (!cmcmd::SymlinkInternal(realName, soName)) { cmSystemTools::ReportLastSystemError("cmake_symlink_library"); @@ -1098,8 +1098,8 @@ int cmcmd::SymlinkLibrary(std::vector<std::string>& args) int cmcmd::SymlinkExecutable(std::vector<std::string>& args) { int result = 0; - std::string realName = args[2]; - std::string name = args[3]; + std::string const& realName = args[2]; + std::string const& name = args[3]; if (name != realName) { if (!cmcmd::SymlinkInternal(realName, name)) { cmSystemTools::ReportLastSystemError("cmake_symlink_executable"); diff --git a/Source/kwsys/CONTRIBUTING.rst b/Source/kwsys/CONTRIBUTING.rst index d71832a..70a313e 100644 --- a/Source/kwsys/CONTRIBUTING.rst +++ b/Source/kwsys/CONTRIBUTING.rst @@ -27,10 +27,12 @@ copies of KWSys within dependent projects can be updated to get the changes. Code Style ========== -We use `clang-format`_ to define our style for C++ code in the KWSys source -tree. See the `.clang-format`_ configuration file for our style settings. -Use ``clang-format`` version 3.8 or higher to format source files. -See also the `clang-format.bash`_ script. +We use `clang-format`_ version **3.8** to define our style for C++ code in +the KWSys source tree. See the `.clang-format`_ configuration file for +our style settings. Use the `clang-format.bash`_ script to format source +code. It automatically runs ``clang-format`` on the set of source files +for which we enforce style. The script also has options to format only +a subset of files, such as those that are locally modified. .. _`clang-format`: http://clang.llvm.org/docs/ClangFormat.html .. _`.clang-format`: .clang-format diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 6b00fc6..bfc895e 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -845,30 +845,6 @@ void SystemInformation::RunMemoryCheck() #define CLASSICAL_CPU_FREQ_LOOP 10000000 #define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31 -#define MMX_FEATURE 0x00000001 -#define MMX_PLUS_FEATURE 0x00000002 -#define SSE_FEATURE 0x00000004 -#define SSE2_FEATURE 0x00000008 -#define AMD_3DNOW_FEATURE 0x00000010 -#define AMD_3DNOW_PLUS_FEATURE 0x00000020 -#define IA64_FEATURE 0x00000040 -#define MP_CAPABLE 0x00000080 -#define HYPERTHREAD_FEATURE 0x00000100 -#define SERIALNUMBER_FEATURE 0x00000200 -#define APIC_FEATURE 0x00000400 -#define SSE_FP_FEATURE 0x00000800 -#define SSE_MMX_FEATURE 0x00001000 -#define CMOV_FEATURE 0x00002000 -#define MTRR_FEATURE 0x00004000 -#define L1CACHE_FEATURE 0x00008000 -#define L2CACHE_FEATURE 0x00010000 -#define L3CACHE_FEATURE 0x00020000 -#define ACPI_FEATURE 0x00040000 -#define THERMALMONITOR_FEATURE 0x00080000 -#define TEMPSENSEDIODE_FEATURE 0x00100000 -#define FREQUENCYID_FEATURE 0x00200000 -#define VOLTAGEID_FREQUENCY 0x00400000 - // Status Flag #define HT_NOT_CAPABLE 0 #define HT_ENABLED 1 @@ -1867,11 +1843,11 @@ int SystemInformationImplementation::GetProcessorCacheSize() int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID) { switch (dwCacheID) { - case L1CACHE_FEATURE: + case SystemInformation::CPU_FEATURE_L1CACHE: return this->Features.L1CacheSize; - case L2CACHE_FEATURE: + case SystemInformation::CPU_FEATURE_L2CACHE: return this->Features.L2CacheSize; - case L3CACHE_FEATURE: + case SystemInformation::CPU_FEATURE_L3CACHE: return this->Features.L3CacheSize; } return -1; @@ -1882,104 +1858,121 @@ bool SystemInformationImplementation::DoesCPUSupportFeature(long int dwFeature) bool bHasFeature = false; // Check for MMX instructions. - if (((dwFeature & MMX_FEATURE) != 0) && this->Features.HasMMX) + if (((dwFeature & SystemInformation::CPU_FEATURE_MMX) != 0) && + this->Features.HasMMX) bHasFeature = true; // Check for MMX+ instructions. - if (((dwFeature & MMX_PLUS_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_MMX_PLUS) != 0) && this->Features.ExtendedFeatures.HasMMXPlus) bHasFeature = true; // Check for SSE FP instructions. - if (((dwFeature & SSE_FEATURE) != 0) && this->Features.HasSSE) + if (((dwFeature & SystemInformation::CPU_FEATURE_SSE) != 0) && + this->Features.HasSSE) bHasFeature = true; // Check for SSE FP instructions. - if (((dwFeature & SSE_FP_FEATURE) != 0) && this->Features.HasSSEFP) + if (((dwFeature & SystemInformation::CPU_FEATURE_SSE_FP) != 0) && + this->Features.HasSSEFP) bHasFeature = true; // Check for SSE MMX instructions. - if (((dwFeature & SSE_MMX_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_SSE_MMX) != 0) && this->Features.ExtendedFeatures.HasSSEMMX) bHasFeature = true; // Check for SSE2 instructions. - if (((dwFeature & SSE2_FEATURE) != 0) && this->Features.HasSSE2) + if (((dwFeature & SystemInformation::CPU_FEATURE_SSE2) != 0) && + this->Features.HasSSE2) bHasFeature = true; // Check for 3DNow! instructions. - if (((dwFeature & AMD_3DNOW_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_AMD_3DNOW) != 0) && this->Features.ExtendedFeatures.Has3DNow) bHasFeature = true; // Check for 3DNow+ instructions. - if (((dwFeature & AMD_3DNOW_PLUS_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS) != 0) && this->Features.ExtendedFeatures.Has3DNowPlus) bHasFeature = true; // Check for IA64 instructions. - if (((dwFeature & IA64_FEATURE) != 0) && this->Features.HasIA64) + if (((dwFeature & SystemInformation::CPU_FEATURE_IA64) != 0) && + this->Features.HasIA64) bHasFeature = true; // Check for MP capable. - if (((dwFeature & MP_CAPABLE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_MP_CAPABLE) != 0) && this->Features.ExtendedFeatures.SupportsMP) bHasFeature = true; // Check for a serial number for the processor. - if (((dwFeature & SERIALNUMBER_FEATURE) != 0) && this->Features.HasSerial) + if (((dwFeature & SystemInformation::CPU_FEATURE_SERIALNUMBER) != 0) && + this->Features.HasSerial) bHasFeature = true; // Check for a local APIC in the processor. - if (((dwFeature & APIC_FEATURE) != 0) && this->Features.HasAPIC) + if (((dwFeature & SystemInformation::CPU_FEATURE_APIC) != 0) && + this->Features.HasAPIC) bHasFeature = true; // Check for CMOV instructions. - if (((dwFeature & CMOV_FEATURE) != 0) && this->Features.HasCMOV) + if (((dwFeature & SystemInformation::CPU_FEATURE_CMOV) != 0) && + this->Features.HasCMOV) bHasFeature = true; // Check for MTRR instructions. - if (((dwFeature & MTRR_FEATURE) != 0) && this->Features.HasMTRR) + if (((dwFeature & SystemInformation::CPU_FEATURE_MTRR) != 0) && + this->Features.HasMTRR) bHasFeature = true; // Check for L1 cache size. - if (((dwFeature & L1CACHE_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_L1CACHE) != 0) && (this->Features.L1CacheSize != -1)) bHasFeature = true; // Check for L2 cache size. - if (((dwFeature & L2CACHE_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_L2CACHE) != 0) && (this->Features.L2CacheSize != -1)) bHasFeature = true; // Check for L3 cache size. - if (((dwFeature & L3CACHE_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_L3CACHE) != 0) && (this->Features.L3CacheSize != -1)) bHasFeature = true; // Check for ACPI capability. - if (((dwFeature & ACPI_FEATURE) != 0) && this->Features.HasACPI) + if (((dwFeature & SystemInformation::CPU_FEATURE_ACPI) != 0) && + this->Features.HasACPI) bHasFeature = true; // Check for thermal monitor support. - if (((dwFeature & THERMALMONITOR_FEATURE) != 0) && this->Features.HasThermal) + if (((dwFeature & SystemInformation::CPU_FEATURE_THERMALMONITOR) != 0) && + this->Features.HasThermal) bHasFeature = true; // Check for temperature sensing diode support. - if (((dwFeature & TEMPSENSEDIODE_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_TEMPSENSEDIODE) != 0) && this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode) bHasFeature = true; // Check for frequency ID support. - if (((dwFeature & FREQUENCYID_FEATURE) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_FREQUENCYID) != 0) && this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID) bHasFeature = true; // Check for voltage ID support. - if (((dwFeature & VOLTAGEID_FREQUENCY) != 0) && + if (((dwFeature & SystemInformation::CPU_FEATURE_VOLTAGEID_FREQUENCY) != + 0) && this->Features.ExtendedFeatures.PowerManagement.HasVoltageID) bHasFeature = true; + // Check for FPU support. + if (((dwFeature & SystemInformation::CPU_FEATURE_FPU) != 0) && + this->Features.HasFPU) + bHasFeature = true; + return bHasFeature; } diff --git a/Source/kwsys/SystemInformation.hxx.in b/Source/kwsys/SystemInformation.hxx.in index 54e7fc1..516c505 100644 --- a/Source/kwsys/SystemInformation.hxx.in +++ b/Source/kwsys/SystemInformation.hxx.in @@ -26,6 +26,33 @@ class @KWSYS_NAMESPACE@_EXPORT SystemInformation SystemInformationImplementation* Implementation; public: + // possible parameter values for DoesCPUSupportFeature() + static const long int CPU_FEATURE_MMX = 1 << 0; + static const long int CPU_FEATURE_MMX_PLUS = 1 << 1; + static const long int CPU_FEATURE_SSE = 1 << 2; + static const long int CPU_FEATURE_SSE2 = 1 << 3; + static const long int CPU_FEATURE_AMD_3DNOW = 1 << 4; + static const long int CPU_FEATURE_AMD_3DNOW_PLUS = 1 << 5; + static const long int CPU_FEATURE_IA64 = 1 << 6; + static const long int CPU_FEATURE_MP_CAPABLE = 1 << 7; + static const long int CPU_FEATURE_HYPERTHREAD = 1 << 8; + static const long int CPU_FEATURE_SERIALNUMBER = 1 << 9; + static const long int CPU_FEATURE_APIC = 1 << 10; + static const long int CPU_FEATURE_SSE_FP = 1 << 11; + static const long int CPU_FEATURE_SSE_MMX = 1 << 12; + static const long int CPU_FEATURE_CMOV = 1 << 13; + static const long int CPU_FEATURE_MTRR = 1 << 14; + static const long int CPU_FEATURE_L1CACHE = 1 << 15; + static const long int CPU_FEATURE_L2CACHE = 1 << 16; + static const long int CPU_FEATURE_L3CACHE = 1 << 17; + static const long int CPU_FEATURE_ACPI = 1 << 18; + static const long int CPU_FEATURE_THERMALMONITOR = 1 << 19; + static const long int CPU_FEATURE_TEMPSENSEDIODE = 1 << 20; + static const long int CPU_FEATURE_FREQUENCYID = 1 << 21; + static const long int CPU_FEATURE_VOLTAGEID_FREQUENCY = 1 << 22; + static const long int CPU_FEATURE_FPU = 1 << 23; + +public: SystemInformation(); ~SystemInformation(); diff --git a/Tests/QtAutoUicInterface/CMakeLists.txt b/Tests/QtAutoUicInterface/CMakeLists.txt index 70175fb..3ea1294 100644 --- a/Tests/QtAutoUicInterface/CMakeLists.txt +++ b/Tests/QtAutoUicInterface/CMakeLists.txt @@ -53,6 +53,12 @@ set_property(TARGET KI18n APPEND PROPERTY # END upstream +if(${CMAKE_GENERATOR} MATCHES "Visual Studio") +set(INC_DIR "include_${CMAKE_BUILD_TYPE}" ) +else() +set(INC_DIR "include" ) +endif() + add_library(LibWidget libwidget.cpp) target_link_libraries(LibWidget KI18n ${QT_GUI_TARGET}) set_property(TARGET LibWidget PROPERTY NO_KUIT_SEMANTIC ON) @@ -64,6 +70,6 @@ target_link_libraries(MyWidget KI18n ${QT_GUI_TARGET}) add_executable(QtAutoUicInterface main.cpp) target_compile_definitions(QtAutoUicInterface PRIVATE - UI_LIBWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/LibWidget_autogen/include/ui_libwidget.h" - UI_MYWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/MyWidget_autogen/include/ui_mywidget.h" + UI_LIBWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/LibWidget_autogen/${INC_DIR}/ui_libwidget.h" + UI_MYWIDGET_H="${CMAKE_CURRENT_BINARY_DIR}/MyWidget_autogen/${INC_DIR}/ui_mywidget.h" ) diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt index 618f79d..3252e3d 100644 --- a/Utilities/cmlibuv/CMakeLists.txt +++ b/Utilities/cmlibuv/CMakeLists.txt @@ -164,7 +164,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") src/unix/linux-inotify.c src/unix/linux-syscalls.c src/unix/linux-syscalls.h + src/unix/procfs-exepath.c src/unix/proctitle.c + src/unix/sysinfo-loadavg.c + src/unix/sysinfo-memory.c ) endif() @@ -249,6 +252,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") ) endif() list(APPEND uv_sources + src/unix/no-proctitle.c src/unix/sunos.c ) endif() diff --git a/Utilities/cmlibuv/include/uv-posix.h b/Utilities/cmlibuv/include/uv-posix.h new file mode 100644 index 0000000..9a96634 --- /dev/null +++ b/Utilities/cmlibuv/include/uv-posix.h @@ -0,0 +1,31 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_POSIX_H +#define UV_POSIX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + struct pollfd* poll_fds; \ + size_t poll_fds_used; \ + size_t poll_fds_size; \ + unsigned char poll_fds_iterating; \ + +#endif /* UV_POSIX_H */ diff --git a/Utilities/cmlibuv/include/uv-unix.h b/Utilities/cmlibuv/include/uv-unix.h index 5440729..d775450 100644 --- a/Utilities/cmlibuv/include/uv-unix.h +++ b/Utilities/cmlibuv/include/uv-unix.h @@ -60,6 +60,8 @@ defined(__OpenBSD__) || \ defined(__NetBSD__) # include "uv-bsd.h" +#elif defined(__CYGWIN__) || defined(__MSYS__) +# include "uv-posix.h" #endif #ifndef PTHREAD_BARRIER_SERIAL_THREAD diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h index ce04875..38f5676 100644 --- a/Utilities/cmlibuv/include/uv.h +++ b/Utilities/cmlibuv/include/uv.h @@ -1082,6 +1082,8 @@ UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size); UV_EXTERN int uv_os_setenv(const char* name, const char* value); UV_EXTERN int uv_os_unsetenv(const char* name); +UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size); + typedef enum { UV_FS_UNKNOWN = -1, diff --git a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c index 0b5653d..4147894 100644 --- a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c +++ b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c @@ -27,7 +27,9 @@ #include <ifaddrs.h> #include <net/if.h> +#if !defined(__CYGWIN__) && !defined(__MSYS__) #include <net/if_dl.h> +#endif static int uv__ifaddr_exclude(struct ifaddrs *ent) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) @@ -107,9 +109,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { for (i = 0; i < *count; i++) { if (strcmp(address->name, ent->ifa_name) == 0) { +#if defined(__CYGWIN__) || defined(__MSYS__) + memset(address->phys_addr, 0, sizeof(address->phys_addr)); +#else struct sockaddr_dl* sa_addr; sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); +#endif } address++; } diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c index 96495b8..30cdaef 100644 --- a/Utilities/cmlibuv/src/unix/core.c +++ b/Utilities/cmlibuv/src/unix/core.c @@ -28,6 +28,7 @@ #include <errno.h> #include <assert.h> #include <unistd.h> +#include <sys/param.h> /* MAXHOSTNAMELEN on Linux and the BSDs */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -42,6 +43,7 @@ #include <pwd.h> #ifdef __sun +# include <netdb.h> /* MAXHOSTNAMELEN on Solaris */ # include <sys/filio.h> # include <sys/types.h> # include <sys/wait.h> @@ -80,6 +82,11 @@ #include <sys/ioctl.h> #endif +/* Fallback for the maximum hostname length */ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + static int uv__run_pending(uv_loop_t* loop); /* Verify that uv_buf_t is ABI-compatible with struct iovec. */ @@ -538,6 +545,7 @@ int uv__nonblock_ioctl(int fd, int set) { } +#if !defined(__CYGWIN__) && !defined(__MSYS__) int uv__cloexec_ioctl(int fd, int set) { int r; @@ -550,6 +558,7 @@ int uv__cloexec_ioctl(int fd, int set) { return 0; } +#endif int uv__nonblock_fcntl(int fd, int set) { @@ -1285,3 +1294,33 @@ int uv_os_unsetenv(const char* name) { return 0; } + + +int uv_os_gethostname(char* buffer, size_t* size) { + /* + On some platforms, if the input buffer is not large enough, gethostname() + succeeds, but truncates the result. libuv can detect this and return ENOBUFS + instead by creating a large enough buffer and comparing the hostname length + to the size input. + */ + char buf[MAXHOSTNAMELEN + 1]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + if (gethostname(buf, sizeof(buf)) != 0) + return -errno; + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return -ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/cygwin.c b/Utilities/cmlibuv/src/unix/cygwin.c new file mode 100644 index 0000000..5a887dd --- /dev/null +++ b/Utilities/cmlibuv/src/unix/cygwin.c @@ -0,0 +1,54 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <sys/sysinfo.h> +#include <unistd.h> + +int uv_uptime(double* uptime) { + struct sysinfo info; + + if (sysinfo(&info) < 0) + return -errno; + + *uptime = info.uptime; + return 0; +} + +int uv_resident_set_memory(size_t* rss) { + /* FIXME: read /proc/meminfo? */ + *rss = 0; + return UV_ENOSYS; +} + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + /* FIXME: read /proc/stat? */ + *cpu_infos = NULL; + *count = 0; + return UV_ENOSYS; +} + +void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { + (void)cpu_infos; + (void)count; +} diff --git a/Utilities/cmlibuv/src/unix/fsevents.c b/Utilities/cmlibuv/src/unix/fsevents.c index d331a13..643e233 100644 --- a/Utilities/cmlibuv/src/unix/fsevents.c +++ b/Utilities/cmlibuv/src/unix/fsevents.c @@ -378,9 +378,6 @@ static void uv__fsevents_destroy_stream(uv_loop_t* loop) { if (state->fsevent_stream == NULL) return; - /* Flush all accumulated events */ - pFSEventStreamFlushSync(state->fsevent_stream); - /* Stop emitting events */ pFSEventStreamStop(state->fsevent_stream); diff --git a/Utilities/cmlibuv/src/unix/linux-core.c b/Utilities/cmlibuv/src/unix/linux-core.c index 646be4f..2866e93 100644 --- a/Utilities/cmlibuv/src/unix/linux-core.c +++ b/Utilities/cmlibuv/src/unix/linux-core.c @@ -472,55 +472,6 @@ uint64_t uv__hrtime(uv_clocktype_t type) { } -void uv_loadavg(double avg[3]) { - struct sysinfo info; - - if (sysinfo(&info) < 0) return; - - avg[0] = (double) info.loads[0] / 65536.0; - avg[1] = (double) info.loads[1] / 65536.0; - avg[2] = (double) info.loads[2] / 65536.0; -} - - -int uv_exepath(char* buffer, size_t* size) { - ssize_t n; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - n = *size - 1; - if (n > 0) - n = readlink("/proc/self/exe", buffer, n); - - if (n == -1) - return -errno; - - buffer[n] = '\0'; - *size = n; - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - struct sysinfo info; - - if (sysinfo(&info) == 0) - return (uint64_t) info.freeram * info.mem_unit; - return 0; -} - - -uint64_t uv_get_total_memory(void) { - struct sysinfo info; - - if (sysinfo(&info) == 0) - return (uint64_t) info.totalram * info.mem_unit; - return 0; -} - - int uv_resident_set_memory(size_t* rss) { char buf[1024]; const char* s; diff --git a/Utilities/cmlibuv/src/unix/no-fsevents.c b/Utilities/cmlibuv/src/unix/no-fsevents.c new file mode 100644 index 0000000..38fb6ab --- /dev/null +++ b/Utilities/cmlibuv/src/unix/no-fsevents.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <errno.h> + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + return -ENOSYS; +} + +int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, + const char* filename, unsigned int flags) { + return -ENOSYS; +} + +int uv_fs_event_stop(uv_fs_event_t* handle) { + return -ENOSYS; +} + +void uv__fs_event_close(uv_fs_event_t* handle) { + UNREACHABLE(); +} diff --git a/Utilities/cmlibuv/src/unix/no-proctitle.c b/Utilities/cmlibuv/src/unix/no-proctitle.c new file mode 100644 index 0000000..a5c19fb --- /dev/null +++ b/Utilities/cmlibuv/src/unix/no-proctitle.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <errno.h> +#include <stddef.h> + +char** uv_setup_args(int argc, char** argv) { + return argv; +} + +int uv_set_process_title(const char* title) { + return 0; +} + +int uv_get_process_title(char* buffer, size_t size) { + if (buffer == NULL || size == 0) + return -EINVAL; + + buffer[0] = '\0'; + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/openbsd.c b/Utilities/cmlibuv/src/unix/openbsd.c index 7e4b253..56f0af1 100644 --- a/Utilities/cmlibuv/src/unix/openbsd.c +++ b/Utilities/cmlibuv/src/unix/openbsd.c @@ -30,7 +30,6 @@ #include <errno.h> #include <fcntl.h> -#include <kvm.h> #include <paths.h> #include <stdlib.h> #include <string.h> diff --git a/Utilities/cmlibuv/src/unix/os390.c b/Utilities/cmlibuv/src/unix/os390.c index e9ba90c..2ba5abf 100644 --- a/Utilities/cmlibuv/src/unix/os390.c +++ b/Utilities/cmlibuv/src/unix/os390.c @@ -663,28 +663,6 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) { return 0; } - -void uv__fs_event_close(uv_fs_event_t* handle) { - UNREACHABLE(); -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - return -ENOSYS; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, - const char* filename, unsigned int flags) { - return -ENOSYS; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - return -ENOSYS; -} - - void uv__io_poll(uv_loop_t* loop, int timeout) { static const int max_safe_timeout = 1789569; struct epoll_event events[1024]; diff --git a/Utilities/cmlibuv/src/unix/pipe.c b/Utilities/cmlibuv/src/unix/pipe.c index 023e965..7ba1bf8 100644 --- a/Utilities/cmlibuv/src/unix/pipe.c +++ b/Utilities/cmlibuv/src/unix/pipe.c @@ -179,6 +179,14 @@ void uv_pipe_connect(uv_connect_t* req, if (r == -1 && errno != EINPROGRESS) { err = -errno; +#if defined(__CYGWIN__) || defined(__MSYS__) + /* EBADF is supposed to mean that the socket fd is bad, but + Cygwin reports EBADF instead of ENOTSOCK when the file is + not a socket. We do not expect to see a bad fd here + (e.g. due to new_sock), so translate the error. */ + if (err == -EBADF) + err = -ENOTSOCK; +#endif goto out; } diff --git a/Utilities/cmlibuv/src/unix/posix-poll.c b/Utilities/cmlibuv/src/unix/posix-poll.c new file mode 100644 index 0000000..3fba96e --- /dev/null +++ b/Utilities/cmlibuv/src/unix/posix-poll.c @@ -0,0 +1,324 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +/* POSIX defines poll() as a portable way to wait on file descriptors. + * Here we maintain a dynamically sized array of file descriptors and + * events to pass as the first argument to poll(). + */ + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <errno.h> +#include <unistd.h> + +int uv__platform_loop_init(uv_loop_t* loop) { + loop->poll_fds = NULL; + loop->poll_fds_used = 0; + loop->poll_fds_size = 0; + loop->poll_fds_iterating = 0; + return 0; +} + +void uv__platform_loop_delete(uv_loop_t* loop) { + uv__free(loop->poll_fds); + loop->poll_fds = NULL; +} + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + +/* Allocate or dynamically resize our poll fds array. */ +static void uv__pollfds_maybe_resize(uv_loop_t* loop) { + size_t i; + size_t n; + struct pollfd* p; + + if (loop->poll_fds_used < loop->poll_fds_size) + return; + + n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64; + p = uv__realloc(loop->poll_fds, n * sizeof(*loop->poll_fds)); + if (p == NULL) + abort(); + + loop->poll_fds = p; + for (i = loop->poll_fds_size; i < n; i++) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + loop->poll_fds_size = n; +} + +/* Primitive swap operation on poll fds array elements. */ +static void uv__pollfds_swap(uv_loop_t* loop, size_t l, size_t r) { + struct pollfd pfd; + pfd = loop->poll_fds[l]; + loop->poll_fds[l] = loop->poll_fds[r]; + loop->poll_fds[r] = pfd; +} + +/* Add a watcher's fd to our poll fds array with its pending events. */ +static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) { + size_t i; + struct pollfd* pe; + + /* If the fd is already in the set just update its events. */ + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == w->fd) { + loop->poll_fds[i].events = w->pevents; + return; + } + } + + /* Otherwise, allocate a new slot in the set for the fd. */ + uv__pollfds_maybe_resize(loop); + pe = &loop->poll_fds[loop->poll_fds_used++]; + pe->fd = w->fd; + pe->events = w->pevents; +} + +/* Remove a watcher's fd from our poll fds array. */ +static void uv__pollfds_del(uv_loop_t* loop, int fd) { + size_t i; + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == fd) { + /* swap to last position and remove */ + --loop->poll_fds_used; + uv__pollfds_swap(loop, i, loop->poll_fds_used); + loop->poll_fds[loop->poll_fds_used].fd = -1; + loop->poll_fds[loop->poll_fds_used].events = 0; + loop->poll_fds[loop->poll_fds_used].revents = 0; + return; + } + } +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + sigset_t* pset; + sigset_t set; + uint64_t time_base; + uint64_t time_diff; + QUEUE* q; + uv__io_t* w; + size_t i; + unsigned int nevents; + int nfds; + int have_signals; + struct pollfd* pe; + int fd; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + /* Take queued watchers and add their fds to our poll fds array. */ + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + uv__pollfds_add(loop, w); + + w->events = w->pevents; + } + + /* Prepare a set of signals to block around poll(), if any. */ + pset = NULL; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + pset = &set; + sigemptyset(pset); + sigaddset(pset, SIGPROF); + } + + assert(timeout >= -1); + time_base = loop->time; + + /* Loop calls to poll() and processing of results. If we get some + * results from poll() but they turn out not to be interesting to + * our caller then we need to loop around and poll() again. + */ + for (;;) { + if (pset != NULL) + if (pthread_sigmask(SIG_BLOCK, pset, NULL)) + abort(); + nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout); + if (pset != NULL) + if (pthread_sigmask(SIG_UNBLOCK, pset, NULL)) + abort(); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + assert(timeout != -1); + return; + } + + if (nfds == -1) { + if (errno != EINTR) + abort(); + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + /* Tell uv__platform_invalidate_fd not to manipulate our array + * while we are iterating over it. + */ + loop->poll_fds_iterating = 1; + + /* Initialize a count of events that we care about. */ + nevents = 0; + have_signals = 0; + + /* Loop over the entire poll fds array looking for returned events. */ + for (i = 0; i < loop->poll_fds_used; i++) { + pe = loop->poll_fds + i; + fd = pe->fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd. */ + if (fd == -1) + continue; + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, ignore. */ + uv__platform_invalidate_fd(loop, fd); + continue; + } + + /* Filter out events that user has not requested us to watch + * (e.g. POLLNVAL). + */ + pe->revents &= w->pevents | POLLERR | POLLHUP; + + if (pe->revents != 0) { + /* Run signal watchers last. */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + w->cb(loop, w, pe->revents); + } + + nevents++; + } + } + + if (have_signals != 0) + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + + loop->poll_fds_iterating = 0; + + /* Purge invalidated fds from our poll fds array. */ + uv__pollfds_del(loop, -1); + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) + return; + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + time_diff = loop->time - time_base; + if (time_diff >= (uint64_t) timeout) + return; + + timeout -= time_diff; + } +} + +/* Remove the given fd from our poll fds array because no one + * is interested in its events anymore. + */ +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + size_t i; + + if (loop->poll_fds_iterating) { + /* uv__io_poll is currently iterating. Just invalidate fd. */ + for (i = 0; i < loop->poll_fds_used; i++) + if (loop->poll_fds[i].fd == fd) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + } else { + /* uv__io_poll is not iterating. Delete fd from the set. */ + uv__pollfds_del(loop, fd); + } +} + +/* Check whether the given fd is supported by poll(). */ +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct pollfd p[1]; + int rv; + + p[0].fd = fd; + p[0].events = POLLIN; + + do + rv = poll(p, 1, 0); + while (rv == -1 && (errno == EINTR || errno == EAGAIN)); + + if (rv == -1) + return -errno; + + if (p[0].revents & POLLNVAL) + return -EINVAL; + + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/procfs-exepath.c b/Utilities/cmlibuv/src/unix/procfs-exepath.c new file mode 100644 index 0000000..5fdb611 --- /dev/null +++ b/Utilities/cmlibuv/src/unix/procfs-exepath.c @@ -0,0 +1,45 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <stddef.h> +#include <unistd.h> + +int uv_exepath(char* buffer, size_t* size) { + ssize_t n; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + n = *size - 1; + if (n > 0) + n = readlink("/proc/self/exe", buffer, n); + + if (n == -1) + return -errno; + + buffer[n] = '\0'; + *size = n; + + return 0; +} diff --git a/Utilities/cmlibuv/src/unix/stream.c b/Utilities/cmlibuv/src/unix/stream.c index dbd04f2..7b23d16 100644 --- a/Utilities/cmlibuv/src/unix/stream.c +++ b/Utilities/cmlibuv/src/unix/stream.c @@ -390,7 +390,7 @@ failed_malloc: int uv__stream_open(uv_stream_t* stream, int fd, int flags) { -#if defined(__APPLE__) || defined(__MVS__) +#if defined(__APPLE__) int enable; #endif @@ -409,7 +409,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) { return -errno; } -#if defined(__APPLE__) || defined(__MVS__) +#if defined(__APPLE__) enable = 1; if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) && errno != ENOTSOCK && @@ -1173,6 +1173,11 @@ static void uv__read(uv_stream_t* stream) { uv__stream_osx_interrupt_select(stream); } stream->read_cb(stream, 0, &buf); +#if defined(__CYGWIN__) || defined(__MSYS__) + } else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) { + uv__stream_eof(stream, &buf); + return; +#endif } else { /* Error. User should call uv_close(). */ stream->read_cb(stream, -errno, &buf); @@ -1405,6 +1410,12 @@ int uv_write2(uv_write_t* req, */ if (uv__handle_fd((uv_handle_t*) send_handle) < 0) return -EBADF; + +#if defined(__CYGWIN__) || defined(__MSYS__) + /* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it. + See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */ + return -ENOSYS; +#endif } /* It's legal for write_queue_size > 0 even when the write_queue is empty; diff --git a/Utilities/cmlibuv/src/unix/sunos.c b/Utilities/cmlibuv/src/unix/sunos.c index d100263..041f3f3 100644 --- a/Utilities/cmlibuv/src/unix/sunos.c +++ b/Utilities/cmlibuv/src/unix/sunos.c @@ -549,25 +549,6 @@ void uv__fs_event_close(uv_fs_event_t* handle) { #endif /* defined(PORT_SOURCE_FILE) */ -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (buffer == NULL || size == 0) - return -EINVAL; - - buffer[0] = '\0'; - return 0; -} - - int uv_resident_set_memory(size_t* rss) { psinfo_t psinfo; int err; diff --git a/Utilities/cmlibuv/src/unix/sysinfo-loadavg.c b/Utilities/cmlibuv/src/unix/sysinfo-loadavg.c new file mode 100644 index 0000000..ebad0e8 --- /dev/null +++ b/Utilities/cmlibuv/src/unix/sysinfo-loadavg.c @@ -0,0 +1,36 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <stdint.h> +#include <sys/sysinfo.h> + +void uv_loadavg(double avg[3]) { + struct sysinfo info; + + if (sysinfo(&info) < 0) return; + + avg[0] = (double) info.loads[0] / 65536.0; + avg[1] = (double) info.loads[1] / 65536.0; + avg[2] = (double) info.loads[2] / 65536.0; +} diff --git a/Utilities/cmlibuv/src/unix/sysinfo-memory.c b/Utilities/cmlibuv/src/unix/sysinfo-memory.c new file mode 100644 index 0000000..23b4fc6 --- /dev/null +++ b/Utilities/cmlibuv/src/unix/sysinfo-memory.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include <stdint.h> +#include <sys/sysinfo.h> + +uint64_t uv_get_free_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.freeram * info.mem_unit; + return 0; +} + +uint64_t uv_get_total_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.totalram * info.mem_unit; + return 0; +} diff --git a/Utilities/cmlibuv/src/win/util.c b/Utilities/cmlibuv/src/win/util.c index 1d64d4c..d2e7f77 100644 --- a/Utilities/cmlibuv/src/win/util.c +++ b/Utilities/cmlibuv/src/win/util.c @@ -59,6 +59,14 @@ # define UNLEN 256 #endif +/* + Max hostname length. The Windows gethostname() documentation states that 256 + bytes will always be large enough to hold the null-terminated hostname. +*/ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + /* Maximum environment variable size, including the terminating null */ #define MAX_ENV_VAR_LENGTH 32767 @@ -1540,3 +1548,29 @@ int uv_os_unsetenv(const char* name) { return 0; } + + +int uv_os_gethostname(char* buffer, size_t* size) { + char buf[MAXHOSTNAMELEN + 1]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + uv__once_init(); /* Initialize winsock */ + + if (gethostname(buf, sizeof(buf)) != 0) + return uv_translate_sys_error(WSAGetLastError()); + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} |