Explorar o código

cmFileCommand: Report keyword errors via argument parser results

Brad King %!s(int64=3) %!d(string=hai) anos
pai
achega
74ec6b63c2

+ 67 - 97
Source/cmFileCommand.cxx

@@ -959,21 +959,19 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args,
   bool removeEnvironmentRPath = false;
   cmArgumentParser<void> parser;
   std::vector<std::string> unknownArgs;
-  std::vector<cm::string_view> missingArgs;
   parser.Bind("FILE"_s, file)
     .Bind("OLD_RPATH"_s, oldRPath)
     .Bind("NEW_RPATH"_s, newRPath)
     .Bind("INSTALL_REMOVE_ENVIRONMENT_RPATH"_s, removeEnvironmentRPath);
-  parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs);
+  ArgumentParser::ParseResult parseResult =
+    parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
   if (!unknownArgs.empty()) {
     status.SetError(
       cmStrCat("RPATH_CHANGE given unknown argument ", unknownArgs.front()));
     return false;
   }
-  if (!missingArgs.empty()) {
-    status.SetError(cmStrCat("RPATH_CHANGE \"", missingArgs.front(),
-                             "\" argument not given value."));
-    return false;
+  if (parseResult.MaybeReportError(status.GetMakefile())) {
+    return true;
   }
   if (file.empty()) {
     status.SetError("RPATH_CHANGE not given FILE option.");
@@ -1023,18 +1021,16 @@ bool HandleRPathSetCommand(std::vector<std::string> const& args,
   cm::optional<std::string> newRPath;
   cmArgumentParser<void> parser;
   std::vector<std::string> unknownArgs;
-  std::vector<cm::string_view> missingArgs;
   parser.Bind("FILE"_s, file).Bind("NEW_RPATH"_s, newRPath);
-  parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs);
+  ArgumentParser::ParseResult parseResult =
+    parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
   if (!unknownArgs.empty()) {
     status.SetError(cmStrCat("RPATH_SET given unrecognized argument \"",
                              unknownArgs.front(), "\"."));
     return false;
   }
-  if (!missingArgs.empty()) {
-    status.SetError(cmStrCat("RPATH_SET \"", missingArgs.front(),
-                             "\" argument not given value."));
-    return false;
+  if (parseResult.MaybeReportError(status.GetMakefile())) {
+    return true;
   }
   if (file.empty()) {
     status.SetError("RPATH_SET not given FILE option.");
@@ -1078,18 +1074,16 @@ bool HandleRPathRemoveCommand(std::vector<std::string> const& args,
   std::string file;
   cmArgumentParser<void> parser;
   std::vector<std::string> unknownArgs;
-  std::vector<cm::string_view> missingArgs;
   parser.Bind("FILE"_s, file);
-  parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs);
+  ArgumentParser::ParseResult parseResult =
+    parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
   if (!unknownArgs.empty()) {
     status.SetError(
       cmStrCat("RPATH_REMOVE given unknown argument ", unknownArgs.front()));
     return false;
   }
-  if (!missingArgs.empty()) {
-    status.SetError(cmStrCat("RPATH_REMOVE \"", missingArgs.front(),
-                             "\" argument not given value."));
-    return false;
+  if (parseResult.MaybeReportError(status.GetMakefile())) {
+    return true;
   }
   if (file.empty()) {
     status.SetError("RPATH_REMOVE not given FILE option.");
@@ -1129,18 +1123,16 @@ bool HandleRPathCheckCommand(std::vector<std::string> const& args,
   cm::optional<std::string> rpath;
   cmArgumentParser<void> parser;
   std::vector<std::string> unknownArgs;
-  std::vector<cm::string_view> missingArgs;
   parser.Bind("FILE"_s, file).Bind("RPATH"_s, rpath);
-  parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs);
+  ArgumentParser::ParseResult parseResult =
+    parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
   if (!unknownArgs.empty()) {
     status.SetError(
       cmStrCat("RPATH_CHECK given unknown argument ", unknownArgs.front()));
     return false;
   }
-  if (!missingArgs.empty()) {
-    status.SetError(cmStrCat("RPATH_CHECK \"", missingArgs.front(),
-                             "\" argument not given value."));
-    return false;
+  if (parseResult.MaybeReportError(status.GetMakefile())) {
+    return true;
   }
   if (file.empty()) {
     status.SetError("RPATH_CHECK not given FILE option.");
@@ -1238,7 +1230,7 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  struct Arguments
+  struct Arguments : public ArgumentParser::ParseResult
   {
     cm::optional<std::string> BaseDirectory;
     bool ExpandTilde = false;
@@ -1249,17 +1241,15 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
       .Bind("EXPAND_TILDE"_s, &Arguments::ExpandTilde);
 
   std::vector<std::string> unparsedArguments;
-  std::vector<cm::string_view> keywordsMissingValue;
-  auto arguments = parser.Parse(cmMakeRange(args).advance(3),
-                                &unparsedArguments, &keywordsMissingValue);
+  auto arguments =
+    parser.Parse(cmMakeRange(args).advance(3), &unparsedArguments);
 
   if (!unparsedArguments.empty()) {
     status.SetError("REAL_PATH called with unexpected arguments");
     return false;
   }
-  if (!keywordsMissingValue.empty()) {
-    status.SetError("BASE_DIRECTORY requires a value");
-    return false;
+  if (arguments.MaybeReportError(status.GetMakefile())) {
+    return true;
   }
 
   if (!arguments.BaseDirectory) {
@@ -2481,7 +2471,7 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  struct Arguments
+  struct Arguments : public ArgumentParser::ParseResult
   {
     cm::optional<std::string> Output;
     cm::optional<std::string> Input;
@@ -2507,17 +2497,13 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
       .Bind("NEWLINE_STYLE"_s, &Arguments::NewLineStyle);
 
   std::vector<std::string> unparsedArguments;
-  std::vector<cm::string_view> keywordsMissingValues;
   std::vector<cm::string_view> parsedKeywords;
   Arguments const arguments =
     parser.Parse(cmMakeRange(args).advance(1), &unparsedArguments,
-                 &keywordsMissingValues, &parsedKeywords);
+                 /*keywordsMissingValue=*/nullptr, &parsedKeywords);
 
-  if (!keywordsMissingValues.empty()) {
-    status.SetError(
-      cmStrCat("GENERATE keywords missing values:\n  ",
-               cmJoin(cmMakeRange(keywordsMissingValues), "\n  ")));
-    return false;
+  if (arguments.MaybeReportError(status.GetMakefile())) {
+    return true;
   }
 
   if (!unparsedArguments.empty()) {
@@ -3031,7 +3017,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
       "\n    ]])");
   }
 
-  struct Arguments
+  struct Arguments : public ArgumentParser::ParseResult
   {
     std::string ResolvedDependenciesVar;
     std::string UnresolvedDependenciesVar;
@@ -3074,10 +3060,8 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
       .Bind("POST_EXCLUDE_FILES_STRICT"_s, &Arguments::PostExcludeFilesStrict);
 
   std::vector<std::string> unrecognizedArguments;
-  std::vector<cm::string_view> keywordsMissingValues;
   auto parsedArgs =
-    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
-                 &keywordsMissingValues);
+    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
   auto argIt = unrecognizedArguments.begin();
   if (argIt != unrecognizedArguments.end()) {
     status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
@@ -3085,12 +3069,9 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  if (!keywordsMissingValues.empty()) {
-    status.SetError(
-      cmStrCat("Keywords missing values:\n  ",
-               cmJoin(cmMakeRange(keywordsMissingValues), "\n  ")));
+  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
     cmSystemTools::SetFatalErrorOccurred();
-    return false;
+    return true;
   }
 
   cmRuntimeDependencyArchive archive(
@@ -3190,7 +3171,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
 bool HandleConfigureCommand(std::vector<std::string> const& args,
                             cmExecutionStatus& status)
 {
-  struct Arguments
+  struct Arguments : public ArgumentParser::ParseResult
   {
     cm::optional<std::string> Output;
     cm::optional<std::string> Content;
@@ -3209,10 +3190,8 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
       .Bind("NEWLINE_STYLE"_s, &Arguments::NewlineStyle);
 
   std::vector<std::string> unrecognizedArguments;
-  std::vector<cm::string_view> keywordsMissingValues;
   auto parsedArgs =
-    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
-                 &keywordsMissingValues);
+    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
 
   auto argIt = unrecognizedArguments.begin();
   if (argIt != unrecognizedArguments.end()) {
@@ -3222,12 +3201,9 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  if (!keywordsMissingValues.empty()) {
-    status.SetError(
-      cmStrCat("CONFIGURE keywords missing values:\n  ",
-               cmJoin(cmMakeRange(keywordsMissingValues), "\n  ")));
+  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
     cmSystemTools::SetFatalErrorOccurred();
-    return false;
+    return true;
   }
 
   if (!parsedArgs.Output) {
@@ -3322,7 +3298,7 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
 bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
                                 cmExecutionStatus& status)
 {
-  struct Arguments
+  struct Arguments : public ArgumentParser::ParseResult
   {
     std::string Output;
     std::string Format;
@@ -3348,10 +3324,8 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
       .Bind("PATHS"_s, &Arguments::Paths);
 
   std::vector<std::string> unrecognizedArguments;
-  std::vector<cm::string_view> keywordsMissingValues;
   auto parsedArgs =
-    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
-                 &keywordsMissingValues);
+    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
   auto argIt = unrecognizedArguments.begin();
   if (argIt != unrecognizedArguments.end()) {
     status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
@@ -3359,12 +3333,9 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  if (!keywordsMissingValues.empty()) {
-    status.SetError(
-      cmStrCat("Keywords missing values:\n  ",
-               cmJoin(cmMakeRange(keywordsMissingValues), "\n  ")));
+  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
     cmSystemTools::SetFatalErrorOccurred();
-    return false;
+    return true;
   }
 
   const char* knownFormats[] = {
@@ -3453,7 +3424,7 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
 bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
 {
-  struct Arguments
+  struct Arguments : public ArgumentParser::ParseResult
   {
     std::string Input;
     bool Verbose = false;
@@ -3472,10 +3443,8 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
                                .Bind("TOUCH"_s, &Arguments::Touch);
 
   std::vector<std::string> unrecognizedArguments;
-  std::vector<cm::string_view> keywordsMissingValues;
   auto parsedArgs =
-    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
-                 &keywordsMissingValues);
+    parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
   auto argIt = unrecognizedArguments.begin();
   if (argIt != unrecognizedArguments.end()) {
     status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
@@ -3483,12 +3452,9 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
     return false;
   }
 
-  if (!keywordsMissingValues.empty()) {
-    status.SetError(
-      cmStrCat("Keywords missing values:\n  ",
-               cmJoin(cmMakeRange(keywordsMissingValues), "\n  ")));
+  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
     cmSystemTools::SetFatalErrorOccurred();
-    return false;
+    return true;
   }
 
   std::string inFile = parsedArgs.Input;
@@ -3543,10 +3509,15 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
   return true;
 }
 
-bool ValidateAndConvertPermissions(const std::vector<std::string>& permissions,
-                                   mode_t& perms, cmExecutionStatus& status)
+bool ValidateAndConvertPermissions(
+  cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> const&
+    permissions,
+  mode_t& perms, cmExecutionStatus& status)
 {
-  for (const auto& i : permissions) {
+  if (!permissions) {
+    return true;
+  }
+  for (const auto& i : *permissions) {
     if (!cmFSPermissions::stringToModeT(i, perms)) {
       status.SetError(i + " is an invalid permission specifier");
       cmSystemTools::SetFatalErrorOccurred();
@@ -3578,11 +3549,14 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
   globber.SetRecurse(recurse);
   globber.SetRecurseListDirs(recurse);
 
-  struct Arguments
+  struct Arguments : public ArgumentParser::ParseResult
   {
-    ArgumentParser::NonEmpty<std::vector<std::string>> Permissions;
-    ArgumentParser::NonEmpty<std::vector<std::string>> FilePermissions;
-    ArgumentParser::NonEmpty<std::vector<std::string>> DirectoryPermissions;
+    cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+      Permissions;
+    cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+      FilePermissions;
+    cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+      DirectoryPermissions;
   };
 
   static auto const parser =
@@ -3592,21 +3566,20 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
       .Bind("DIRECTORY_PERMISSIONS"_s, &Arguments::DirectoryPermissions);
 
   std::vector<std::string> pathEntries;
-  std::vector<cm::string_view> keywordsMissingValues;
-  Arguments parsedArgs = parser.Parse(cmMakeRange(args).advance(1),
-                                      &pathEntries, &keywordsMissingValues);
+  Arguments parsedArgs =
+    parser.Parse(cmMakeRange(args).advance(1), &pathEntries);
 
   // check validity of arguments
-  if (parsedArgs.Permissions.empty() && parsedArgs.FilePermissions.empty() &&
-      parsedArgs.DirectoryPermissions.empty()) // no permissions given
+  if (!parsedArgs.Permissions && !parsedArgs.FilePermissions &&
+      !parsedArgs.DirectoryPermissions) // no permissions given
   {
     status.SetError("No permissions given");
     cmSystemTools::SetFatalErrorOccurred();
     return false;
   }
 
-  if (!parsedArgs.Permissions.empty() && !parsedArgs.FilePermissions.empty() &&
-      !parsedArgs.DirectoryPermissions.empty()) // all keywords are used
+  if (parsedArgs.Permissions && parsedArgs.FilePermissions &&
+      parsedArgs.DirectoryPermissions) // all keywords are used
   {
     status.SetError("Remove either PERMISSIONS or FILE_PERMISSIONS or "
                     "DIRECTORY_PERMISSIONS from the invocation");
@@ -3614,12 +3587,9 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
     return false;
   }
 
-  if (!keywordsMissingValues.empty()) {
-    for (const auto& i : keywordsMissingValues) {
-      status.SetError(cmStrCat(i, " is not given any arguments"));
-      cmSystemTools::SetFatalErrorOccurred();
-    }
-    return false;
+  if (parsedArgs.MaybeReportError(status.GetMakefile())) {
+    cmSystemTools::SetFatalErrorOccurred();
+    return true;
   }
 
   // validate permissions
@@ -3663,7 +3633,7 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
     if (cmSystemTools::FileExists(i, true)) {
       bool success = true;
       const mode_t& filePermissions =
-        parsedArgs.FilePermissions.empty() ? perms : fperms;
+        parsedArgs.FilePermissions ? fperms : perms;
       if (filePermissions) {
         success = SetPermissions(i, filePermissions, status);
       }
@@ -3675,7 +3645,7 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
     else if (cmSystemTools::FileIsDirectory(i)) {
       bool success = true;
       const mode_t& directoryPermissions =
-        parsedArgs.DirectoryPermissions.empty() ? perms : dperms;
+        parsedArgs.DirectoryPermissions ? dperms : perms;
       if (directoryPermissions) {
         success = SetPermissions(i, directoryPermissions, status);
       }

+ 15 - 5
Tests/RunCMake/File_Archive/create-missing-args-stderr.txt

@@ -1,9 +1,19 @@
 ^CMake Error at create-missing-args.cmake:[0-9]+ \(file\):
-  file Keywords missing values:
+  Error after keyword "COMPRESSION":
+
+    missing required value
+
+  Error after keyword "COMPRESSION_LEVEL":
+
+    missing required value
+
+  Error after keyword "FORMAT":
+
+    missing required value
+
+  Error after keyword "OUTPUT":
+
+    missing required value
 
-    OUTPUT
-    FORMAT
-    COMPRESSION
-    COMPRESSION_LEVEL
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)$

+ 7 - 3
Tests/RunCMake/File_Archive/extract-missing-args-stderr.txt

@@ -1,7 +1,11 @@
 ^CMake Error at extract-missing-args.cmake:[0-9]+ \(file\):
-  file Keywords missing values:
+  Error after keyword "DESTINATION":
+
+    missing required value
+
+  Error after keyword "INPUT":
+
+    missing required value
 
-    INPUT
-    DESTINATION
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)$

+ 3 - 2
Tests/RunCMake/File_Configure/BadArgContent-stderr.txt

@@ -1,6 +1,7 @@
 CMake Error at BadArgContent.cmake:[0-9]+ \(file\):
-  file CONFIGURE keywords missing values:
+  Error after keyword "CONTENT":
+
+    missing required value
 
-    CONTENT
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)

+ 3 - 2
Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt

@@ -1,6 +1,7 @@
 CMake Error at BadArgOutput.cmake:[0-9]+ \(file\):
-  file CONFIGURE keywords missing values:
+  Error after keyword "OUTPUT":
+
+    missing required value
 
-    OUTPUT
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)

+ 3 - 2
Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt

@@ -1,6 +1,7 @@
 CMake Error at EmptyCondition1.cmake:2 \(file\):
-  file GENERATE keywords missing values:
+  Error after keyword "CONDITION":
+
+    missing required value
 
-    CONDITION
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)

+ 3 - 2
Tests/RunCMake/File_Generate/NewLineStyle-NoArg-stderr.txt

@@ -1,6 +1,7 @@
 CMake Error at NewLineStyle-NoArg.cmake:[0-9]+ \(file\):
-  file GENERATE keywords missing values:
+  Error after keyword "NEWLINE_STYLE":
+
+    missing required value
 
-    NEWLINE_STYLE
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)

+ 3 - 1
Tests/RunCMake/file-CHMOD/missing-dir-perms-stderr.txt

@@ -1,3 +1,5 @@
 ^CMake Error at [^
 ]*/missing-dir-perms.cmake:[0-9]+ \(file\):
-  file DIRECTORY_PERMISSIONS is not given any arguments$
+  Error after keyword "DIRECTORY_PERMISSIONS":
+
+    missing required value$

+ 3 - 1
Tests/RunCMake/file-CHMOD/missing-file-perms-stderr.txt

@@ -1,3 +1,5 @@
 ^CMake Error at [^
 ]*/missing-file-perms.cmake:[0-9]+ \(file\):
-  file FILE_PERMISSIONS is not given any arguments$
+  Error after keyword "FILE_PERMISSIONS":
+
+    missing required value$

+ 3 - 1
Tests/RunCMake/file-CHMOD/missing-perms-stderr.txt

@@ -1,3 +1,5 @@
 ^CMake Error at [^
 ]*/missing-perms.cmake:[0-9]+ \(file\):
-  file PERMISSIONS is not given any arguments$
+  Error after keyword "PERMISSIONS":
+
+    missing required value$

+ 15 - 5
Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt

@@ -13,11 +13,21 @@ Call Stack \(most recent call first\):
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
 
 CMake Error at badargs2\.cmake:[0-9]+ \(file\):
-  file Keywords missing values:
+  Error after keyword "BUNDLE_EXECUTABLE":
+
+    missing required value
+
+  Error after keyword "CONFLICTING_DEPENDENCIES_PREFIX":
+
+    missing required value
+
+  Error after keyword "RESOLVED_DEPENDENCIES_VAR":
+
+    missing required value
+
+  Error after keyword "UNRESOLVED_DEPENDENCIES_VAR":
+
+    missing required value
 
-    RESOLVED_DEPENDENCIES_VAR
-    UNRESOLVED_DEPENDENCIES_VAR
-    CONFLICTING_DEPENDENCIES_PREFIX
-    BUNDLE_EXECUTABLE
 Call Stack \(most recent call first\):
   CMakeLists\.txt:[0-9]+ \(include\)$

+ 7 - 2
Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt

@@ -1,2 +1,7 @@
-CMake Error at REAL_PATH-no-base-dir.cmake:[0-9]+ \(file\):
-  file BASE_DIRECTORY requires a value
+^CMake Error at REAL_PATH-no-base-dir.cmake:[0-9]+ \(file\):
+  Error after keyword "BASE_DIRECTORY":
+
+    missing required value
+
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$