From 7d4b2b2ef36c73c36eefd464fbb17bf34ebdb5fe Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 20 Nov 2013 02:12:48 +0100 Subject: [PATCH 1/2] cmStandardIncludes: Add new cmHasLiteralPrefix function. This allows avoiding error-prone hard-coding of literal string lengths. Borland is not able to process the template version of this method. Make it use the macro version instead. This means that Borland will also use the macro versions of cmArray*. --- Source/cmStandardIncludes.h | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index 18d017dca..1ccec6876 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -377,13 +377,31 @@ static thisClass* SafeDownCast(cmObject *c) \ return 0;\ } +inline bool cmHasLiteralPrefixImpl(const std::string &str1, + const char *str2, + size_t N) +{ + return strncmp(str1.c_str(), str2, N) == 0; +} + +inline bool cmHasLiteralPrefixImpl(const char* str1, + const char *str2, + size_t N) +{ + return strncmp(str1, str2, N) == 0; +} + #if defined(_MSC_VER) && _MSC_VER < 1300 \ - || defined(__GNUC__) && __GNUC__ < 3 + || defined(__GNUC__) && __GNUC__ < 3 \ + || defined(__BORLANDC__) #define cmArrayBegin(a) a #define cmArraySize(a) (sizeof(a)/sizeof(*a)) #define cmArrayEnd(a) a + cmArraySize(a) +#define cmHasLiteralPrefix(STR1, STR2) \ + cmHasLiteralPrefixImpl(STR1, "" STR2 "", sizeof(STR2) - 1) + #else template @@ -393,6 +411,12 @@ const T* cmArrayEnd(const T (&a)[N]) { return a + N; } template size_t cmArraySize(const T (&)[N]) { return N; } +template +bool cmHasLiteralPrefix(T str1, const char (&str2)[N]) +{ + return cmHasLiteralPrefixImpl(str1, str2, N - 1); +} + #endif struct cmStrCmp { From 4fe963f656c48b1f2fd0b4a2f427bb376f619c37 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 20 Nov 2013 02:12:00 +0100 Subject: [PATCH 2/2] Use new cmHasLiteralPrefix function --- Source/CTest/cmCTestBuildHandler.cxx | 4 ++-- Source/CTest/cmCTestGIT.cxx | 6 +++--- Source/cmCTest.cxx | 4 ++-- Source/cmExportFileGenerator.cxx | 2 +- Source/cmExportInstallFileGenerator.cxx | 8 ++++---- Source/cmGeneratorExpressionDAGChecker.cxx | 6 +++--- Source/cmGeneratorExpressionEvaluator.cxx | 4 ++-- Source/cmGlobalVisualStudio10Generator.cxx | 2 +- Source/cmGlobalVisualStudio11Generator.cxx | 2 +- Source/cmGlobalVisualStudio12Generator.cxx | 2 +- Source/cmOutputRequiredFilesCommand.cxx | 2 +- Source/cmSetCommand.cxx | 2 +- Source/cmTarget.cxx | 14 +++++++------- Source/cmTargetCompileDefinitionsCommand.cxx | 2 +- Source/cmUnsetCommand.cxx | 2 +- Source/cmakemain.cxx | 5 ++--- 16 files changed, 33 insertions(+), 34 deletions(-) diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index 39eeb70a3..e480fff9a 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -763,7 +763,7 @@ void cmCTestBuildHandler::GenerateXMLLaunchedFragment(std::ostream& os, bool cmCTestBuildHandler::IsLaunchedErrorFile(const char* fname) { // error-{hash}.xml - return (strncmp(fname, "error-", 6) == 0 && + return (cmHasLiteralPrefix(fname, "error-") && strcmp(fname+strlen(fname)-4, ".xml") == 0); } @@ -771,7 +771,7 @@ bool cmCTestBuildHandler::IsLaunchedErrorFile(const char* fname) bool cmCTestBuildHandler::IsLaunchedWarningFile(const char* fname) { // warning-{hash}.xml - return (strncmp(fname, "warning-", 8) == 0 && + return (cmHasLiteralPrefix(fname, "warning-") && strcmp(fname+strlen(fname)-4, ".xml") == 0); } diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx index 5b3449181..725f613d9 100644 --- a/Source/CTest/cmCTestGIT.cxx +++ b/Source/CTest/cmCTestGIT.cxx @@ -536,11 +536,11 @@ private: void DoHeaderLine() { // Look for header fields that we need. - if(strncmp(this->Line.c_str(), "commit ", 7) == 0) + if(cmHasLiteralPrefix(this->Line.c_str(), "commit ")) { this->Rev.Rev = this->Line.c_str()+7; } - else if(strncmp(this->Line.c_str(), "author ", 7) == 0) + else if(cmHasLiteralPrefix(this->Line.c_str(), "author ")) { Person author; this->ParsePerson(this->Line.c_str()+7, author); @@ -548,7 +548,7 @@ private: this->Rev.EMail = author.EMail; this->Rev.Date = this->FormatDateTime(author); } - else if(strncmp(this->Line.c_str(), "committer ", 10) == 0) + else if(cmHasLiteralPrefix(this->Line.c_str(), "committer ")) { Person committer; this->ParsePerson(this->Line.c_str()+10, committer); diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index bfabc9f2d..125a3bfae 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1131,11 +1131,11 @@ int cmCTest::GetTestModelFromString(const char* str) return cmCTest::EXPERIMENTAL; } std::string rstr = cmSystemTools::LowerCase(str); - if ( strncmp(rstr.c_str(), "cont", 4) == 0 ) + if ( cmHasLiteralPrefix(rstr.c_str(), "cont") ) { return cmCTest::CONTINUOUS; } - if ( strncmp(rstr.c_str(), "nigh", 4) == 0 ) + if ( cmHasLiteralPrefix(rstr.c_str(), "nigh") ) { return cmCTest::NIGHTLY; } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index fdc075e84..2ce445838 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -240,7 +240,7 @@ static bool checkInterfaceDirs(const std::string &prepro, { continue; } - if (strncmp(li->c_str(), "${_IMPORT_PREFIX}", 17) == 0) + if (cmHasLiteralPrefix(li->c_str(), "${_IMPORT_PREFIX}")) { continue; } diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 133944ee5..ad17556a3 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -81,10 +81,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) os << "# Compute the installation prefix relative to this file.\n" << "get_filename_component(_IMPORT_PREFIX" << " \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"; - if(strncmp(absDestS.c_str(), "/lib/", 5) == 0 || - strncmp(absDestS.c_str(), "/lib64/", 7) == 0 || - strncmp(absDestS.c_str(), "/usr/lib/", 9) == 0 || - strncmp(absDestS.c_str(), "/usr/lib64/", 11) == 0) + if(cmHasLiteralPrefix(absDestS.c_str(), "/lib/") || + cmHasLiteralPrefix(absDestS.c_str(), "/lib64/") || + cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib/") || + cmHasLiteralPrefix(absDestS.c_str(), "/usr/lib64/")) { // Handle "/usr move" symlinks created by some Linux distros. os << diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 92dc054c9..7399c7bfa 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -173,8 +173,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char *tgt) return (strcmp(prop, "LINK_LIBRARIES") == 0 || strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 || strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 - || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 25) == 0 - || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 34) == 0) + || cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") + || cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_")) || strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0; } @@ -200,7 +200,7 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions() const const char *prop = this->Property.c_str(); return (strcmp(prop, "COMPILE_DEFINITIONS") == 0 || strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0 - || strncmp(prop, "COMPILE_DEFINITIONS_", 20) == 0); + || cmHasLiteralPrefix(prop, "COMPILE_DEFINITIONS_")); } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 2ae5a2238..67972b976 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -902,8 +902,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(POPULATE_INTERFACE_PROPERTY_NAME) // Note that the above macro terminates with an else - /* else */ if (strncmp(propertyName.c_str(), - "COMPILE_DEFINITIONS_", 20) == 0) + /* else */ if (cmHasLiteralPrefix(propertyName.c_str(), + "COMPILE_DEFINITIONS_")) { interfacePropertyName = "INTERFACE_COMPILE_DEFINITIONS"; } diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 29401c6bf..7d4abbdef 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -28,7 +28,7 @@ static const char* cmVS10GenName(const char* name, std::string& genName) return 0; } const char* p = name + sizeof(vs10generatorName) - 6; - if(strncmp(p, " 2010", 5) == 0) + if(cmHasLiteralPrefix(p, " 2010")) { p += 5; } diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index f1d731248..1f0c47a35 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -23,7 +23,7 @@ static const char* cmVS11GenName(const char* name, std::string& genName) return 0; } const char* p = name + sizeof(vs11generatorName) - 6; - if(strncmp(p, " 2012", 5) == 0) + if(cmHasLiteralPrefix(p, " 2012")) { p += 5; } diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx index edd556730..3074794b8 100644 --- a/Source/cmGlobalVisualStudio12Generator.cxx +++ b/Source/cmGlobalVisualStudio12Generator.cxx @@ -23,7 +23,7 @@ static const char* cmVS12GenName(const char* name, std::string& genName) return 0; } const char* p = name + sizeof(vs12generatorName) - 6; - if(strncmp(p, " 2013", 5) == 0) + if(cmHasLiteralPrefix(p, " 2013")) { p += 5; } diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx index 16b2beae9..5de36ed09 100644 --- a/Source/cmOutputRequiredFilesCommand.cxx +++ b/Source/cmOutputRequiredFilesCommand.cxx @@ -32,7 +32,7 @@ void cmLBDepend::DependWalk(cmDependInformation* info) std::string line; while(cmSystemTools::GetLineFromStream(fin, line)) { - if(!strncmp(line.c_str(), "#include", 8)) + if(cmHasLiteralPrefix(line.c_str(), "#include")) { // if it is an include line then create a string class std::string currentline = line; diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx index bb193bf9f..36363a134 100644 --- a/Source/cmSetCommand.cxx +++ b/Source/cmSetCommand.cxx @@ -23,7 +23,7 @@ bool cmSetCommand // watch for ENV signatures const char* variable = args[0].c_str(); // VAR is always first - if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5) + if (cmHasLiteralPrefix(variable, "ENV{") && strlen(variable) > 5) { // what is the variable name char *varName = new char [strlen(variable)]; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c9905b643..5fd963648 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -560,7 +560,7 @@ cmSourceFile* cmTarget::AddSource(const char* s) //---------------------------------------------------------------------------- void cmTarget::ProcessSourceExpression(std::string const& expr) { - if(strncmp(expr.c_str(), "$') { std::string objLibName = expr.substr(17, expr.size()-18); @@ -2199,11 +2199,11 @@ void cmTarget::GetCompileDefinitions(std::vector &list, void cmTarget::MaybeInvalidatePropertyCache(const char* prop) { // Wipe out maps caching information affected by this property. - if(this->IsImported() && strncmp(prop, "IMPORTED", 8) == 0) + if(this->IsImported() && cmHasLiteralPrefix(prop, "IMPORTED")) { this->Internal->ImportInfoMap.clear(); } - if(!this->IsImported() && strncmp(prop, "LINK_INTERFACE_", 15) == 0) + if(!this->IsImported() && cmHasLiteralPrefix(prop, "LINK_INTERFACE_")) { this->ClearLinkMaps(); } @@ -2279,21 +2279,21 @@ static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value, void cmTarget::CheckProperty(const char* prop, cmMakefile* context) { // Certain properties need checking. - if(strncmp(prop, "LINK_INTERFACE_LIBRARIES", 24) == 0) + if(cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) { if(const char* value = this->GetProperty(prop)) { cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false); } } - if(strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES", 33) == 0) + if(cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) { if(const char* value = this->GetProperty(prop)) { cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true); } } - if(strncmp(prop, "INTERFACE_LINK_LIBRARIES", 24) == 0) + if(cmHasLiteralPrefix(prop, "INTERFACE_LINK_LIBRARIES")) { if(const char* value = this->GetProperty(prop)) { @@ -2595,7 +2595,7 @@ const char *cmTarget::GetProperty(const char* prop, } // Support "LOCATION_". - if(strncmp(prop, "LOCATION_", 9) == 0) + if(cmHasLiteralPrefix(prop, "LOCATION_")) { if (!this->HandleLocationPropertyPolicy()) { diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx index 46c9666ef..b567252aa 100644 --- a/Source/cmTargetCompileDefinitionsCommand.cxx +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -44,7 +44,7 @@ std::string cmTargetCompileDefinitionsCommand for(std::vector::const_iterator it = content.begin(); it != content.end(); ++it) { - if (strncmp(it->c_str(), "-D", 2) == 0) + if (cmHasLiteralPrefix(it->c_str(), "-D")) { defs += sep + it->substr(2); } diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx index 84f3029a2..053cdfc7d 100644 --- a/Source/cmUnsetCommand.cxx +++ b/Source/cmUnsetCommand.cxx @@ -24,7 +24,7 @@ bool cmUnsetCommand::InitialPass(std::vector const& args, const char* variable = args[0].c_str(); // unset(ENV{VAR}) - if (!strncmp(variable,"ENV{",4) && strlen(variable) > 5) + if (cmHasLiteralPrefix(variable, "ENV{") && strlen(variable) > 5) { // what is the variable name char *envVarName = new char [strlen(variable)]; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 6ef0579b9..882b072a8 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -273,7 +273,7 @@ int do_cmake(int ac, char** av) list_all_cached = true; list_help = true; } - else if (strncmp(av[i], "-P", strlen("-P")) == 0) + else if (cmHasLiteralPrefix(av[i], "-P")) { if ( i == ac -1 ) { @@ -287,8 +287,7 @@ int do_cmake(int ac, char** av) args.push_back(av[i]); } } - else if (strncmp(av[i], "--find-package", - strlen("--find-package")) == 0) + else if (cmHasLiteralPrefix(av[i], "--find-package")) { workingMode = cmake::FIND_PACKAGE_MODE; args.push_back(av[i]);