1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #pragma once
4 
5 #include "cmConfigure.h" // IWYU pragma: keep
6 
7 #include <chrono>
8 #include <deque>
9 #include <iosfwd>
10 #include <string>
11 #include <vector>
12 
13 #include <stddef.h>
14 
15 #include "cmsys/RegularExpression.hxx"
16 
17 #include "cmCTestGenericHandler.h"
18 #include "cmDuration.h"
19 #include "cmProcessOutput.h"
20 
21 class cmMakefile;
22 class cmStringReplaceHelper;
23 class cmXMLWriter;
24 
25 /** \class cmCTestBuildHandler
26  * \brief A class that handles ctest -S invocations
27  *
28  */
29 class cmCTestBuildHandler : public cmCTestGenericHandler
30 {
31 public:
32   using Superclass = cmCTestGenericHandler;
33   using Encoding = cmProcessOutput::Encoding;
34 
35   /*
36    * The main entry point for this class
37    */
38   int ProcessHandler() override;
39 
40   cmCTestBuildHandler();
41 
42   void PopulateCustomVectors(cmMakefile* mf) override;
43 
44   /**
45    * Initialize handler
46    */
47   void Initialize() override;
48 
GetTotalErrors()49   int GetTotalErrors() { return this->TotalErrors; }
GetTotalWarnings()50   int GetTotalWarnings() { return this->TotalWarnings; }
51 
52 private:
53   std::string GetMakeCommand();
54 
55   //! Run command specialized for make and configure. Returns process status
56   // and retVal is return value or exception.
57   int RunMakeCommand(const std::string& command, int* retVal, const char* dir,
58                      int timeout, std::ostream& ofs,
59                      Encoding encoding = cmProcessOutput::Auto);
60 
61   enum
62   {
63     b_REGULAR_LINE,
64     b_WARNING_LINE,
65     b_ERROR_LINE
66   };
67 
68   class cmCTestCompileErrorWarningRex
69   {
70   public:
cmCTestCompileErrorWarningRex()71     cmCTestCompileErrorWarningRex() {}
72     int FileIndex;
73     int LineIndex;
74     cmsys::RegularExpression RegularExpression;
75   };
76 
77   struct cmCTestBuildErrorWarning
78   {
79     bool Error;
80     int LogLine;
81     std::string Text;
82     std::string SourceFile;
83     std::string SourceFileTail;
84     int LineNumber;
85     std::string PreContext;
86     std::string PostContext;
87   };
88 
89   // generate the XML output
90   void GenerateXMLHeader(cmXMLWriter& xml);
91   void GenerateXMLLaunched(cmXMLWriter& xml);
92   void GenerateXMLLogScraped(cmXMLWriter& xml);
93   void GenerateXMLFooter(cmXMLWriter& xml, cmDuration elapsed_build_time);
94   bool IsLaunchedErrorFile(const char* fname);
95   bool IsLaunchedWarningFile(const char* fname);
96 
97   std::string StartBuild;
98   std::string EndBuild;
99   std::chrono::system_clock::time_point StartBuildTime;
100   std::chrono::system_clock::time_point EndBuildTime;
101 
102   std::vector<std::string> CustomErrorMatches;
103   std::vector<std::string> CustomErrorExceptions;
104   std::vector<std::string> CustomWarningMatches;
105   std::vector<std::string> CustomWarningExceptions;
106   std::vector<std::string> ReallyCustomWarningMatches;
107   std::vector<std::string> ReallyCustomWarningExceptions;
108   std::vector<cmCTestCompileErrorWarningRex> ErrorWarningFileLineRegex;
109 
110   std::vector<cmsys::RegularExpression> ErrorMatchRegex;
111   std::vector<cmsys::RegularExpression> ErrorExceptionRegex;
112   std::vector<cmsys::RegularExpression> WarningMatchRegex;
113   std::vector<cmsys::RegularExpression> WarningExceptionRegex;
114 
115   using t_BuildProcessingQueueType = std::deque<char>;
116 
117   void ProcessBuffer(const char* data, size_t length, size_t& tick,
118                      size_t tick_len, std::ostream& ofs,
119                      t_BuildProcessingQueueType* queue);
120   int ProcessSingleLine(const char* data);
121 
122   t_BuildProcessingQueueType BuildProcessingQueue;
123   t_BuildProcessingQueueType BuildProcessingErrorQueue;
124   size_t BuildOutputLogSize;
125   std::vector<char> CurrentProcessingLine;
126 
127   std::string SimplifySourceDir;
128   std::string SimplifyBuildDir;
129   size_t OutputLineCounter;
130   using t_ErrorsAndWarningsVector = std::vector<cmCTestBuildErrorWarning>;
131   t_ErrorsAndWarningsVector ErrorsAndWarnings;
132   t_ErrorsAndWarningsVector::iterator LastErrorOrWarning;
133   size_t PostContextCount;
134   size_t MaxPreContext;
135   size_t MaxPostContext;
136   std::deque<std::string> PreContext;
137 
138   int TotalErrors;
139   int TotalWarnings;
140   char LastTickChar;
141 
142   bool ErrorQuotaReached;
143   bool WarningQuotaReached;
144 
145   int MaxErrors;
146   int MaxWarnings;
147 
148   // Used to remove ANSI color codes before checking for errors and warnings.
149   cmStringReplaceHelper* ColorRemover;
150 
151   bool UseCTestLaunch;
152   std::string CTestLaunchDir;
153   class LaunchHelper;
154 
155   friend class LaunchHelper;
156   class FragmentCompare;
157 };
158