| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086 | 
							- /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 
-    file Copyright.txt or https://cmake.org/licensing for details.  */
 
- #include "cmQtAutoMocUic.h"
 
- #include <algorithm>
 
- #include <initializer_list>
 
- #include <list>
 
- #include <set>
 
- #include <utility>
 
- #include "cm_memory.hxx"
 
- #include "cmAlgorithms.h"
 
- #include "cmCryptoHash.h"
 
- #include "cmGeneratedFileStream.h"
 
- #include "cmMakefile.h"
 
- #include "cmQtAutoGen.h"
 
- #include "cmStringAlgorithms.h"
 
- #include "cmSystemTools.h"
 
- #include "cmake.h"
 
- #include "cmsys/FStream.hxx"
 
- #if defined(__APPLE__)
 
- #  include <unistd.h>
 
- #endif
 
- static constexpr std::size_t MocUnderscoreLength = 4; // Length of "moc_"
 
- static constexpr std::size_t UiUnderscoreLength = 3;  // Length of "ui_"
 
- cmQtAutoMocUic::IncludeKeyT::IncludeKeyT(std::string const& key,
 
-                                          std::size_t basePrefixLength)
 
-   : Key(key)
 
-   , Dir(SubDirPrefix(key))
 
-   , Base(cmSystemTools::GetFilenameWithoutLastExtension(key))
 
- {
 
-   if (basePrefixLength != 0) {
 
-     Base = Base.substr(basePrefixLength);
 
-   }
 
- }
 
- void cmQtAutoMocUic::ParseCacheT::FileT::Clear()
 
- {
 
-   Moc.Macro.clear();
 
-   Moc.Include.Underscore.clear();
 
-   Moc.Include.Dot.clear();
 
-   Moc.Depends.clear();
 
-   Uic.Include.clear();
 
-   Uic.Depends.clear();
 
- }
 
- cmQtAutoMocUic::ParseCacheT::FileHandleT cmQtAutoMocUic::ParseCacheT::Get(
 
-   std::string const& fileName) const
 
- {
 
-   auto it = Map_.find(fileName);
 
-   if (it != Map_.end()) {
 
-     return it->second;
 
-   }
 
-   return FileHandleT();
 
- }
 
- cmQtAutoMocUic::ParseCacheT::GetOrInsertT
 
- cmQtAutoMocUic::ParseCacheT::GetOrInsert(std::string const& fileName)
 
- {
 
-   // Find existing entry
 
-   {
 
-     auto it = Map_.find(fileName);
 
-     if (it != Map_.end()) {
 
-       return GetOrInsertT{ it->second, false };
 
-     }
 
-   }
 
-   // Insert new entry
 
-   return GetOrInsertT{
 
-     Map_.emplace(fileName, std::make_shared<FileT>()).first->second, true
 
-   };
 
- }
 
- cmQtAutoMocUic::ParseCacheT::ParseCacheT() = default;
 
- cmQtAutoMocUic::ParseCacheT::~ParseCacheT() = default;
 
- void cmQtAutoMocUic::ParseCacheT::Clear()
 
- {
 
-   Map_.clear();
 
- }
 
- bool cmQtAutoMocUic::ParseCacheT::ReadFromFile(std::string const& fileName)
 
- {
 
-   cmsys::ifstream fin(fileName.c_str());
 
-   if (!fin) {
 
-     return false;
 
-   }
 
-   FileHandleT fileHandle;
 
-   std::string line;
 
-   while (std::getline(fin, line)) {
 
-     // Check if this an empty or a comment line
 
-     if (line.empty() || line.front() == '#') {
 
-       continue;
 
-     }
 
-     // Drop carriage return character at the end
 
-     if (line.back() == '\r') {
 
-       line.pop_back();
 
-       if (line.empty()) {
 
-         continue;
 
-       }
 
-     }
 
-     // Check if this a file name line
 
-     if (line.front() != ' ') {
 
-       fileHandle = GetOrInsert(line).first;
 
-       continue;
 
-     }
 
-     // Bad line or bad file handle
 
-     if (!fileHandle || (line.size() < 6)) {
 
-       continue;
 
-     }
 
-     constexpr std::size_t offset = 5;
 
-     if (cmHasLiteralPrefix(line, " mmc:")) {
 
-       fileHandle->Moc.Macro = line.substr(offset);
 
-       continue;
 
-     }
 
-     if (cmHasLiteralPrefix(line, " miu:")) {
 
-       fileHandle->Moc.Include.Underscore.emplace_back(line.substr(offset),
 
-                                                       MocUnderscoreLength);
 
-       continue;
 
-     }
 
-     if (cmHasLiteralPrefix(line, " mid:")) {
 
-       fileHandle->Moc.Include.Dot.emplace_back(line.substr(offset), 0);
 
-       continue;
 
-     }
 
-     if (cmHasLiteralPrefix(line, " mdp:")) {
 
-       fileHandle->Moc.Depends.emplace_back(line.substr(offset));
 
-       continue;
 
-     }
 
-     if (cmHasLiteralPrefix(line, " uic:")) {
 
-       fileHandle->Uic.Include.emplace_back(line.substr(offset),
 
-                                            UiUnderscoreLength);
 
-       continue;
 
-     }
 
-     if (cmHasLiteralPrefix(line, " udp:")) {
 
-       fileHandle->Uic.Depends.emplace_back(line.substr(offset));
 
-       continue;
 
-     }
 
-   }
 
-   return true;
 
- }
 
- bool cmQtAutoMocUic::ParseCacheT::WriteToFile(std::string const& fileName)
 
- {
 
-   cmGeneratedFileStream ofs(fileName);
 
-   if (!ofs) {
 
-     return false;
 
-   }
 
-   ofs << "# Generated by CMake. Changes will be overwritten." << std::endl;
 
-   for (auto const& pair : Map_) {
 
-     ofs << pair.first << std::endl;
 
-     FileT const& file = *pair.second;
 
-     if (!file.Moc.Macro.empty()) {
 
-       ofs << " mmc:" << file.Moc.Macro << std::endl;
 
-     }
 
-     for (IncludeKeyT const& item : file.Moc.Include.Underscore) {
 
-       ofs << " miu:" << item.Key << std::endl;
 
-     }
 
-     for (IncludeKeyT const& item : file.Moc.Include.Dot) {
 
-       ofs << " mid:" << item.Key << std::endl;
 
-     }
 
-     for (std::string const& item : file.Moc.Depends) {
 
-       ofs << " mdp:" << item << std::endl;
 
-     }
 
-     for (IncludeKeyT const& item : file.Uic.Include) {
 
-       ofs << " uic:" << item.Key << std::endl;
 
-     }
 
-     for (std::string const& item : file.Uic.Depends) {
 
-       ofs << " udp:" << item << std::endl;
 
-     }
 
-   }
 
-   return ofs.Close();
 
- }
 
- cmQtAutoMocUic::BaseSettingsT::BaseSettingsT() = default;
 
- cmQtAutoMocUic::BaseSettingsT::~BaseSettingsT() = default;
 
- cmQtAutoMocUic::MocSettingsT::MocSettingsT()
 
- {
 
-   RegExpInclude.compile(
 
-     "(^|\n)[ \t]*#[ \t]*include[ \t]+"
 
-     "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
 
- }
 
- cmQtAutoMocUic::MocSettingsT::~MocSettingsT() = default;
 
- bool cmQtAutoMocUic::MocSettingsT::skipped(std::string const& fileName) const
 
- {
 
-   return (!Enabled || (SkipList.find(fileName) != SkipList.end()));
 
- }
 
- std::string cmQtAutoMocUic::MocSettingsT::MacrosString() const
 
- {
 
-   std::string res;
 
-   const auto itB = MacroFilters.cbegin();
 
-   const auto itE = MacroFilters.cend();
 
-   const auto itL = itE - 1;
 
-   auto itC = itB;
 
-   for (; itC != itE; ++itC) {
 
-     // Separator
 
-     if (itC != itB) {
 
-       if (itC != itL) {
 
-         res += ", ";
 
-       } else {
 
-         res += " or ";
 
-       }
 
-     }
 
-     // Key
 
-     res += itC->Key;
 
-   }
 
-   return res;
 
- }
 
- cmQtAutoMocUic::UicSettingsT::UicSettingsT()
 
- {
 
-   RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+"
 
-                         "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
 
- }
 
- cmQtAutoMocUic::UicSettingsT::~UicSettingsT() = default;
 
- bool cmQtAutoMocUic::UicSettingsT::skipped(std::string const& fileName) const
 
- {
 
-   return (!Enabled || (SkipList.find(fileName) != SkipList.end()));
 
- }
 
- void cmQtAutoMocUic::JobT::LogError(GenT genType,
 
-                                     cm::string_view message) const
 
- {
 
-   Gen()->AbortError();
 
-   Gen()->Log().Error(genType, message);
 
- }
 
- void cmQtAutoMocUic::JobT::LogFileError(GenT genType, cm::string_view filename,
 
-                                         cm::string_view message) const
 
- {
 
-   Gen()->AbortError();
 
-   Gen()->Log().ErrorFile(genType, filename, message);
 
- }
 
- void cmQtAutoMocUic::JobT::LogCommandError(
 
-   GenT genType, cm::string_view message,
 
-   std::vector<std::string> const& command, std::string const& output) const
 
- {
 
-   Gen()->AbortError();
 
-   Gen()->Log().ErrorCommand(genType, message, command, output);
 
- }
 
- bool cmQtAutoMocUic::JobT::RunProcess(GenT genType,
 
-                                       cmWorkerPool::ProcessResultT& result,
 
-                                       std::vector<std::string> const& command,
 
-                                       std::string* infoMessage)
 
- {
 
-   // Log command
 
-   if (Log().Verbose()) {
 
-     cm::string_view info;
 
-     if (infoMessage != nullptr) {
 
-       info = *infoMessage;
 
-     }
 
-     Log().Info(genType,
 
-                cmStrCat(info,
 
-                         info.empty() || cmHasSuffix(info, '\n') ? "" : "\n",
 
-                         QuotedCommand(command), '\n'));
 
-   }
 
-   return cmWorkerPool::JobT::RunProcess(result, command,
 
-                                         BaseConst().AutogenBuildDir);
 
- }
 
- void cmQtAutoMocUic::JobMocPredefsT::Process()
 
- {
 
-   // (Re)generate moc_predefs.h on demand
 
-   std::unique_ptr<std::string> reason;
 
-   if (Log().Verbose()) {
 
-     reason = cm::make_unique<std::string>();
 
-   }
 
-   if (!Update(reason.get())) {
 
-     return;
 
-   }
 
-   std::string const& predefsFileRel = MocConst().PredefsFileRel;
 
-   std::string const& predefsFileAbs = MocConst().PredefsFileAbs;
 
-   {
 
-     cmWorkerPool::ProcessResultT result;
 
-     {
 
-       // Compose command
 
-       std::vector<std::string> cmd = MocConst().PredefsCmd;
 
-       // Add includes
 
-       cmAppend(cmd, MocConst().Includes);
 
-       // Add definitions
 
-       for (std::string const& def : MocConst().Definitions) {
 
-         cmd.emplace_back("-D" + def);
 
-       }
 
-       // Execute command
 
-       if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
 
-         LogCommandError(GenT::MOC,
 
-                         cmStrCat("The content generation command for ",
 
-                                  Quoted(predefsFileRel), " failed.\n",
 
-                                  result.ErrorMessage),
 
-                         cmd, result.StdOut);
 
-         return;
 
-       }
 
-     }
 
-     // (Re)write predefs file only on demand
 
-     if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) {
 
-       if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) {
 
-         LogFileError(GenT::MOC, predefsFileAbs,
 
-                      cmStrCat("Writing ", Quoted(predefsFileRel), " failed."));
 
-         return;
 
-       }
 
-     } else {
 
-       // Touch to update the time stamp
 
-       if (Log().Verbose()) {
 
-         Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel));
 
-       }
 
-       if (!cmSystemTools::Touch(predefsFileAbs, false)) {
 
-         LogFileError(
 
-           GenT::MOC, predefsFileAbs,
 
-           cmStrCat("Touching ", Quoted(predefsFileAbs), " failed."));
 
-         return;
 
-       }
 
-     }
 
-   }
 
-   // Read file time afterwards
 
-   if (!MocEval().PredefsTime.Load(predefsFileAbs)) {
 
-     LogFileError(GenT::MOC, predefsFileAbs, "File time reading failed.");
 
-     return;
 
-   }
 
- }
 
- bool cmQtAutoMocUic::JobMocPredefsT::Update(std::string* reason) const
 
- {
 
-   // Test if the file exists
 
-   if (!MocEval().PredefsTime.Load(MocConst().PredefsFileAbs)) {
 
-     if (reason != nullptr) {
 
-       *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel),
 
-                          ", because it doesn't exist.");
 
-     }
 
-     return true;
 
-   }
 
-   // Test if the settings changed
 
-   if (MocConst().SettingsChanged) {
 
-     if (reason != nullptr) {
 
-       *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel),
 
-                          ", because the moc settings changed.");
 
-     }
 
-     return true;
 
-   }
 
-   // Test if the executable is newer
 
-   {
 
-     std::string const& exec = MocConst().PredefsCmd.at(0);
 
-     cmFileTime execTime;
 
-     if (execTime.Load(exec)) {
 
-       if (MocEval().PredefsTime.Older(execTime)) {
 
-         if (reason != nullptr) {
 
-           *reason = cmStrCat("Generating ", Quoted(MocConst().PredefsFileRel),
 
-                              " because it is older than ", Quoted(exec), '.');
 
-         }
 
-         return true;
 
-       }
 
-     }
 
-   }
 
-   return false;
 
- }
 
- bool cmQtAutoMocUic::JobParseT::ReadFile()
 
- {
 
-   // Clear old parse information
 
-   FileHandle->ParseData->Clear();
 
-   std::string const& fileName = FileHandle->FileName;
 
-   // Write info
 
-   if (Log().Verbose()) {
 
-     Log().Info(GenT::GEN, "Parsing " + Quoted(fileName));
 
-   }
 
-   // Read file content
 
-   {
 
-     std::string error;
 
-     if (!cmQtAutoGenerator::FileRead(Content, fileName, &error)) {
 
-       LogFileError(GenT::GEN, fileName, "Could not read the file: " + error);
 
-       return false;
 
-     }
 
-   }
 
-   // Warn if empty
 
-   if (Content.empty()) {
 
-     Log().WarningFile(GenT::GEN, fileName, "The file is empty.");
 
-     return false;
 
-   }
 
-   return true;
 
- }
 
- void cmQtAutoMocUic::JobParseT::CreateKeys(std::vector<IncludeKeyT>& container,
 
-                                            std::set<std::string> const& source,
 
-                                            std::size_t basePrefixLength)
 
- {
 
-   if (source.empty()) {
 
-     return;
 
-   }
 
-   container.reserve(source.size());
 
-   for (std::string const& src : source) {
 
-     container.emplace_back(src, basePrefixLength);
 
-   }
 
- }
 
- void cmQtAutoMocUic::JobParseT::MocMacro()
 
- {
 
-   for (KeyExpT const& filter : MocConst().MacroFilters) {
 
-     // Run a simple find string check
 
-     if (Content.find(filter.Key) == std::string::npos) {
 
-       continue;
 
-     }
 
-     // Run the expensive regular expression check loop
 
-     cmsys::RegularExpressionMatch match;
 
-     if (filter.Exp.find(Content.c_str(), match)) {
 
-       // Keep detected macro name
 
-       FileHandle->ParseData->Moc.Macro = filter.Key;
 
-       return;
 
-     }
 
-   }
 
- }
 
- void cmQtAutoMocUic::JobParseT::MocDependecies()
 
- {
 
-   if (MocConst().DependFilters.empty()) {
 
-     return;
 
-   }
 
-   // Find dependency strings
 
-   std::set<std::string> parseDepends;
 
-   for (KeyExpT const& filter : MocConst().DependFilters) {
 
-     // Run a simple find string check
 
-     if (Content.find(filter.Key) == std::string::npos) {
 
-       continue;
 
-     }
 
-     // Run the expensive regular expression check loop
 
-     const char* contentChars = Content.c_str();
 
-     cmsys::RegularExpressionMatch match;
 
-     while (filter.Exp.find(contentChars, match)) {
 
-       {
 
-         std::string dep = match.match(1);
 
-         if (!dep.empty()) {
 
-           parseDepends.emplace(std::move(dep));
 
-         }
 
-       }
 
-       contentChars += match.end();
 
-     }
 
-   }
 
-   // Store dependency strings
 
-   {
 
-     auto& Depends = FileHandle->ParseData->Moc.Depends;
 
-     Depends.reserve(parseDepends.size());
 
-     for (std::string const& item : parseDepends) {
 
-       Depends.emplace_back(item);
 
-       // Replace end of line characters in filenames
 
-       std::string& path = Depends.back();
 
-       std::replace(path.begin(), path.end(), '\n', ' ');
 
-       std::replace(path.begin(), path.end(), '\r', ' ');
 
-     }
 
-   }
 
- }
 
- void cmQtAutoMocUic::JobParseT::MocIncludes()
 
- {
 
-   if (Content.find("moc") == std::string::npos) {
 
-     return;
 
-   }
 
-   std::set<std::string> underscore;
 
-   std::set<std::string> dot;
 
-   {
 
-     const char* contentChars = Content.c_str();
 
-     cmsys::RegularExpression const& regExp = MocConst().RegExpInclude;
 
-     cmsys::RegularExpressionMatch match;
 
-     while (regExp.find(contentChars, match)) {
 
-       std::string incString = match.match(2);
 
-       std::string const incBase =
 
-         cmSystemTools::GetFilenameWithoutLastExtension(incString);
 
-       if (cmHasLiteralPrefix(incBase, "moc_")) {
 
-         // moc_<BASE>.cpp
 
-         // Remove the moc_ part from the base name
 
-         underscore.emplace(std::move(incString));
 
-       } else {
 
-         // <BASE>.moc
 
-         dot.emplace(std::move(incString));
 
-       }
 
-       // Forward content pointer
 
-       contentChars += match.end();
 
-     }
 
-   }
 
-   auto& Include = FileHandle->ParseData->Moc.Include;
 
-   CreateKeys(Include.Underscore, underscore, MocUnderscoreLength);
 
-   CreateKeys(Include.Dot, dot, 0);
 
- }
 
- void cmQtAutoMocUic::JobParseT::UicIncludes()
 
- {
 
-   if (Content.find("ui_") == std::string::npos) {
 
-     return;
 
-   }
 
-   std::set<std::string> includes;
 
-   {
 
-     const char* contentChars = Content.c_str();
 
-     cmsys::RegularExpression const& regExp = UicConst().RegExpInclude;
 
-     cmsys::RegularExpressionMatch match;
 
-     while (regExp.find(contentChars, match)) {
 
-       includes.emplace(match.match(2));
 
-       // Forward content pointer
 
-       contentChars += match.end();
 
-     }
 
-   }
 
-   CreateKeys(FileHandle->ParseData->Uic.Include, includes, UiUnderscoreLength);
 
- }
 
- void cmQtAutoMocUic::JobParseHeaderT::Process()
 
- {
 
-   if (!ReadFile()) {
 
-     return;
 
-   }
 
-   // Moc parsing
 
-   if (FileHandle->Moc) {
 
-     MocMacro();
 
-     MocDependecies();
 
-   }
 
-   // Uic parsing
 
-   if (FileHandle->Uic) {
 
-     UicIncludes();
 
-   }
 
- }
 
- void cmQtAutoMocUic::JobParseSourceT::Process()
 
- {
 
-   if (!ReadFile()) {
 
-     return;
 
-   }
 
-   // Moc parsing
 
-   if (FileHandle->Moc) {
 
-     MocMacro();
 
-     MocDependecies();
 
-     MocIncludes();
 
-   }
 
-   // Uic parsing
 
-   if (FileHandle->Uic) {
 
-     UicIncludes();
 
-   }
 
- }
 
- void cmQtAutoMocUic::JobEvaluateT::Process()
 
- {
 
-   // Evaluate for moc
 
-   if (MocConst().Enabled) {
 
-     // Evaluate headers
 
-     for (auto const& pair : BaseEval().Headers) {
 
-       if (!MocEvalHeader(pair.second)) {
 
-         return;
 
-       }
 
-     }
 
-     // Evaluate sources
 
-     for (auto const& pair : BaseEval().Sources) {
 
-       if (!MocEvalSource(pair.second)) {
 
-         return;
 
-       }
 
-     }
 
-   }
 
-   // Evaluate for uic
 
-   if (UicConst().Enabled) {
 
-     if (!UicEval(BaseEval().Headers) || !UicEval(BaseEval().Sources)) {
 
-       return;
 
-     }
 
-   }
 
-   // Add discovered header parse jobs
 
-   Gen()->CreateParseJobs<JobParseHeaderT>(MocEval().HeadersDiscovered);
 
-   // Add generate job after
 
-   Gen()->WorkerPool().EmplaceJob<JobGenerateT>();
 
- }
 
- bool cmQtAutoMocUic::JobEvaluateT::MocEvalHeader(SourceFileHandleT source)
 
- {
 
-   SourceFileT const& sourceFile = *source;
 
-   auto const& parseData = sourceFile.ParseData->Moc;
 
-   if (!source->Moc) {
 
-     return true;
 
-   }
 
-   if (!parseData.Macro.empty()) {
 
-     // Create a new mapping
 
-     MappingHandleT handle = std::make_shared<MappingT>();
 
-     handle->SourceFile = std::move(source);
 
-     // Absolute build path
 
-     if (BaseConst().MultiConfig) {
 
-       handle->OutputFile = Gen()->AbsoluteIncludePath(sourceFile.BuildPath);
 
-     } else {
 
-       handle->OutputFile = Gen()->AbsoluteBuildPath(sourceFile.BuildPath);
 
-     }
 
-     // Register mapping in headers map
 
-     MocRegisterMapping(handle, true);
 
-   }
 
-   return true;
 
- }
 
- bool cmQtAutoMocUic::JobEvaluateT::MocEvalSource(
 
-   SourceFileHandleT const& source)
 
- {
 
-   SourceFileT const& sourceFile = *source;
 
-   auto const& parseData = sourceFile.ParseData->Moc;
 
-   if (!sourceFile.Moc ||
 
-       (parseData.Macro.empty() && parseData.Include.Underscore.empty() &&
 
-        parseData.Include.Dot.empty())) {
 
-     return true;
 
-   }
 
-   std::string const sourceDir = SubDirPrefix(sourceFile.FileName);
 
-   std::string const sourceBase =
 
-     cmSystemTools::GetFilenameWithoutLastExtension(sourceFile.FileName);
 
-   // For relaxed mode check if the own "moc_" or ".moc" file is included
 
-   bool const relaxedMode = MocConst().RelaxedMode;
 
-   bool sourceIncludesMocUnderscore = false;
 
-   bool sourceIncludesDotMoc = false;
 
-   // Check if the sources own "moc_" or ".moc" file is included
 
-   if (relaxedMode) {
 
-     for (IncludeKeyT const& incKey : parseData.Include.Underscore) {
 
-       if (incKey.Base == sourceBase) {
 
-         sourceIncludesMocUnderscore = true;
 
-         break;
 
-       }
 
-     }
 
-   }
 
-   for (IncludeKeyT const& incKey : parseData.Include.Dot) {
 
-     if (incKey.Base == sourceBase) {
 
-       sourceIncludesDotMoc = true;
 
-       break;
 
-     }
 
-   }
 
-   // Check if this source needs to be moc processed but doesn't.
 
-   if (!sourceIncludesDotMoc && !parseData.Macro.empty() &&
 
-       !(relaxedMode && sourceIncludesMocUnderscore)) {
 
-     LogFileError(GenT::MOC, sourceFile.FileName,
 
-                  cmStrCat("The file contains a ", Quoted(parseData.Macro),
 
-                           " macro, but does not include ",
 
-                           Quoted(sourceBase + ".moc"),
 
-                           "!\nConsider to\n  - add #include \"", sourceBase,
 
-                           ".moc\"\n  - enable SKIP_AUTOMOC for this file"));
 
-     return false;
 
-   }
 
-   // Evaluate "moc_" includes
 
-   for (IncludeKeyT const& incKey : parseData.Include.Underscore) {
 
-     std::string const headerBase = incKey.Dir + incKey.Base;
 
-     SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
 
-     if (!header) {
 
-       LogFileError(GenT::MOC, sourceFile.FileName,
 
-                    cmStrCat("The file includes the moc file ",
 
-                             Quoted(incKey.Key),
 
-                             ",\nbut the header could not be found "
 
-                             "in the following locations\n",
 
-                             MocMessageTestHeaders(headerBase)));
 
-       return false;
 
-     }
 
-     // The include might be handled differently in relaxed mode
 
-     if (relaxedMode && !sourceIncludesDotMoc && !parseData.Macro.empty() &&
 
-         (incKey.Base == sourceBase)) {
 
-       // The <BASE>.cpp file includes a Qt macro but does not include the
 
-       // <BASE>.moc file. In this case, the moc_<BASE>.cpp should probably
 
-       // be generated from <BASE>.cpp instead of <BASE>.h, because otherwise
 
-       // it won't build. But warn, since this is not how it is supposed to be
 
-       // used. This is for KDE4 compatibility.
 
-       // Issue a warning
 
-       Log().WarningFile(
 
-         GenT::MOC, sourceFile.FileName,
 
-         cmStrCat("The file contains a ", Quoted(parseData.Macro),
 
-                  " macro, but does not include ", Quoted(sourceBase + ".moc"),
 
-                  ".\nInstead it includes ", Quoted(incKey.Key),
 
-                  ".\nRunning moc on the source\n  ",
 
-                  Quoted(sourceFile.FileName), "!\nBetter include ",
 
-                  Quoted(sourceBase + ".moc"),
 
-                  " for compatibility with regular mode.\n",
 
-                  "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
 
-       // Create mapping
 
-       if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
 
-         return false;
 
-       }
 
-       continue;
 
-     }
 
-     // Check if header is skipped
 
-     if (MocConst().skipped(header->FileName)) {
 
-       continue;
 
-     }
 
-     // Create mapping
 
-     if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) {
 
-       return false;
 
-     }
 
-   }
 
-   // Evaluate ".moc" includes
 
-   if (relaxedMode) {
 
-     // Relaxed mode
 
-     for (IncludeKeyT const& incKey : parseData.Include.Dot) {
 
-       // Check if this is the sources own .moc file
 
-       bool const ownMoc = (incKey.Base == sourceBase);
 
-       if (ownMoc && !parseData.Macro.empty()) {
 
-         // Create mapping for the regular use case
 
-         if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
 
-           return false;
 
-         }
 
-         continue;
 
-       }
 
-       // Try to find a header instead but issue a warning.
 
-       // This is for KDE4 compatibility.
 
-       std::string const headerBase = incKey.Dir + incKey.Base;
 
-       SourceFileHandleT header = MocFindIncludedHeader(sourceDir, headerBase);
 
-       if (!header) {
 
-         LogFileError(
 
-           GenT::MOC, sourceFile.FileName,
 
-           cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
 
-                    ",\nwhich seems to be the moc file from a different source "
 
-                    "file.\nCMAKE_AUTOMOC_RELAXED_MODE: Also a matching header"
 
-                    "could not be found in the following locations\n",
 
-                    MocMessageTestHeaders(headerBase)));
 
-         return false;
 
-       }
 
-       // Check if header is skipped
 
-       if (MocConst().skipped(header->FileName)) {
 
-         continue;
 
-       }
 
-       // Issue a warning
 
-       if (ownMoc && parseData.Macro.empty()) {
 
-         Log().WarningFile(
 
-           GenT::MOC, sourceFile.FileName,
 
-           cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
 
-                    ", but does not contain a\n", MocConst().MacrosString(),
 
-                    " macro.\nRunning moc on the header\n  ",
 
-                    Quoted(header->FileName), "!\nBetter include ",
 
-                    Quoted("moc_" + incKey.Base + ".cpp"),
 
-                    " for a compatibility with regular mode.\n",
 
-                    "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
 
-       } else {
 
-         Log().WarningFile(
 
-           GenT::MOC, sourceFile.FileName,
 
-           cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
 
-                    " instead of ", Quoted("moc_" + incKey.Base + ".cpp"),
 
-                    ".\nRunning moc on the header\n  ",
 
-                    Quoted(header->FileName), "!\nBetter include ",
 
-                    Quoted("moc_" + incKey.Base + ".cpp"),
 
-                    " for compatibility with regular mode.\n",
 
-                    "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n"));
 
-       }
 
-       // Create mapping
 
-       if (!MocRegisterIncluded(incKey.Key, source, std::move(header), true)) {
 
-         return false;
 
-       }
 
-     }
 
-   } else {
 
-     // Strict mode
 
-     for (IncludeKeyT const& incKey : parseData.Include.Dot) {
 
-       // Check if this is the sources own .moc file
 
-       bool const ownMoc = (incKey.Base == sourceBase);
 
-       if (!ownMoc) {
 
-         // Don't allow <BASE>.moc include other than own in regular mode
 
-         LogFileError(
 
-           GenT::MOC, sourceFile.FileName,
 
-           cmStrCat("The file includes the moc file ", Quoted(incKey.Key),
 
-                    ",\nwhich seems to be the moc file from a different "
 
-                    "source file.\nThis is not supported.  Include ",
 
-                    Quoted(sourceBase + ".moc"),
 
-                    " to run moc on this source file."));
 
-         return false;
 
-       }
 
-       // Accept but issue a warning if moc isn't required
 
-       if (parseData.Macro.empty()) {
 
-         Log().WarningFile(GenT::MOC, sourceFile.FileName,
 
-                           cmStrCat("The file includes the moc file ",
 
-                                    Quoted(incKey.Key),
 
-                                    ", but does not contain a ",
 
-                                    MocConst().MacrosString(), " macro."));
 
-       }
 
-       // Create mapping
 
-       if (!MocRegisterIncluded(incKey.Key, source, source, false)) {
 
-         return false;
 
-       }
 
-     }
 
-   }
 
-   return true;
 
- }
 
- cmQtAutoMocUic::SourceFileHandleT
 
- cmQtAutoMocUic::JobEvaluateT::MocFindIncludedHeader(
 
-   std::string const& includerDir, std::string const& includeBase) const
 
- {
 
-   // Search in vicinity of the source
 
-   {
 
-     SourceFileHandleT res = MocFindHeader(includerDir + includeBase);
 
-     if (res) {
 
-       return res;
 
-     }
 
-   }
 
-   // Search in include directories
 
-   for (std::string const& path : MocConst().IncludePaths) {
 
-     std::string testPath = cmStrCat(path, '/', includeBase);
 
-     SourceFileHandleT res = MocFindHeader(testPath);
 
-     if (res) {
 
-       return res;
 
-     }
 
-   }
 
-   // Return without success
 
-   return SourceFileHandleT();
 
- }
 
- cmQtAutoMocUic::SourceFileHandleT cmQtAutoMocUic::JobEvaluateT::MocFindHeader(
 
-   std::string const& basePath) const
 
- {
 
-   std::string testPath;
 
-   testPath.reserve(basePath.size() + 8);
 
-   for (std::string const& ext : BaseConst().HeaderExtensions) {
 
-     testPath.clear();
 
-     testPath += basePath;
 
-     testPath += '.';
 
-     testPath += ext;
 
-     cmFileTime fileTime;
 
-     if (fileTime.Load(testPath)) {
 
-       // Compute real path of the file
 
-       testPath = cmSystemTools::GetRealPath(testPath);
 
-       // Return a known file if it exists already
 
-       {
 
-         auto it = BaseEval().Headers.find(testPath);
 
-         if (it != BaseEval().Headers.end()) {
 
-           return it->second;
 
-         }
 
-       }
 
-       // Created and return discovered file entry
 
-       SourceFileHandleT& res = MocEval().HeadersDiscovered[testPath];
 
-       if (!res) {
 
-         res = std::make_shared<SourceFileT>(testPath);
 
-         res->FileTime = fileTime;
 
-         res->Moc = true;
 
-       }
 
-       return res;
 
-     }
 
-   }
 
-   // Return without success
 
-   return SourceFileHandleT();
 
- }
 
- std::string cmQtAutoMocUic::JobEvaluateT::MocMessageTestHeaders(
 
-   cm::string_view fileBase) const
 
- {
 
-   std::string const exts =
 
-     cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","), '}');
 
-   // Compose result string
 
-   std::string res = cmStrCat("  ", fileBase, exts, '\n');
 
-   for (std::string const& path : MocConst().IncludePaths) {
 
-     res += cmStrCat("  ", path, '/', fileBase, exts, '\n');
 
-   }
 
-   return res;
 
- }
 
- bool cmQtAutoMocUic::JobEvaluateT::MocRegisterIncluded(
 
-   std::string const& includeString, SourceFileHandleT includerFileHandle,
 
-   SourceFileHandleT sourceFileHandle, bool sourceIsHeader) const
 
- {
 
-   // Check if this file is already included
 
-   MappingHandleT& handle = MocEval().Includes[includeString];
 
-   if (handle) {
 
-     // Check if the output file would be generated from different source files
 
-     if (handle->SourceFile != sourceFileHandle) {
 
-       std::string files =
 
-         cmStrCat("  ", Quoted(includerFileHandle->FileName), '\n');
 
-       for (auto const& item : handle->IncluderFiles) {
 
-         files += cmStrCat("  ", Quoted(item->FileName), '\n');
 
-       }
 
-       LogError(
 
-         GenT::MOC,
 
-         cmStrCat("The source files\n", files,
 
-                  "contain the same include string ", Quoted(includeString),
 
-                  ", but\nthe moc file would be generated from different "
 
-                  "source files\n  ",
 
-                  Quoted(sourceFileHandle->FileName), " and\n  ",
 
-                  Quoted(handle->SourceFile->FileName),
 
-                  ".\nConsider to\n"
 
-                  "  - not include the \"moc_<NAME>.cpp\" file\n"
 
-                  "  - add a directory prefix to a \"<NAME>.moc\" include "
 
-                  "(e.g \"sub/<NAME>.moc\")\n"
 
-                  "  - rename the source file(s)\n"));
 
-       return false;
 
-     }
 
-     // The same mapping already exists. Just add to the includers list.
 
-     handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
 
-     return true;
 
-   }
 
-   // Create a new mapping
 
-   handle = std::make_shared<MappingT>();
 
-   handle->IncludeString = includeString;
 
-   handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
 
-   handle->SourceFile = std::move(sourceFileHandle);
 
-   handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
 
-   // Register mapping in sources/headers map
 
-   MocRegisterMapping(handle, sourceIsHeader);
 
-   return true;
 
- }
 
- void cmQtAutoMocUic::JobEvaluateT::MocRegisterMapping(
 
-   MappingHandleT mappingHandle, bool sourceIsHeader) const
 
- {
 
-   auto& regMap =
 
-     sourceIsHeader ? MocEval().HeaderMappings : MocEval().SourceMappings;
 
-   // Check if source file already gets mapped
 
-   auto& regHandle = regMap[mappingHandle->SourceFile->FileName];
 
-   if (!regHandle) {
 
-     // Yet unknown mapping
 
-     regHandle = std::move(mappingHandle);
 
-   } else {
 
-     // Mappings with include string override those without
 
-     if (!mappingHandle->IncludeString.empty()) {
 
-       regHandle = std::move(mappingHandle);
 
-     }
 
-   }
 
- }
 
- bool cmQtAutoMocUic::JobEvaluateT::UicEval(SourceFileMapT const& fileMap)
 
- {
 
-   for (auto const& pair : fileMap) {
 
-     if (!UicEvalFile(pair.second)) {
 
-       return false;
 
-     }
 
-   }
 
-   return true;
 
- }
 
- bool cmQtAutoMocUic::JobEvaluateT::UicEvalFile(
 
-   SourceFileHandleT const& sourceFileHandle)
 
- {
 
-   SourceFileT const& sourceFile = *sourceFileHandle;
 
-   auto const& Include = sourceFile.ParseData->Uic.Include;
 
-   if (!sourceFile.Uic || Include.empty()) {
 
-     return true;
 
-   }
 
-   std::string const sourceDir = SubDirPrefix(sourceFile.FileName);
 
-   for (IncludeKeyT const& incKey : Include) {
 
-     // Find .ui file name
 
-     SourceFileHandleT uiFileHandle =
 
-       UicFindIncludedUi(sourceFile.FileName, sourceDir, incKey);
 
-     if (!uiFileHandle || UicConst().skipped(uiFileHandle->FileName)) {
 
-       continue;
 
-     }
 
-     // Register mapping
 
-     if (!UicRegisterMapping(incKey.Key, std::move(uiFileHandle),
 
-                             sourceFileHandle)) {
 
-       return false;
 
-     }
 
-   }
 
-   return true;
 
- }
 
- bool cmQtAutoMocUic::JobEvaluateT::UicRegisterMapping(
 
-   std::string const& includeString, SourceFileHandleT uiFileHandle,
 
-   SourceFileHandleT includerFileHandle)
 
- {
 
-   auto& Includes = Gen()->UicEval().Includes;
 
-   auto it = Includes.find(includeString);
 
-   if (it != Includes.end()) {
 
-     MappingHandleT const& handle = it->second;
 
-     if (handle->SourceFile != uiFileHandle) {
 
-       // The output file already gets generated - from a different .ui file!
 
-       std::string files =
 
-         cmStrCat("  ", Quoted(includerFileHandle->FileName), '\n');
 
-       for (auto const& item : handle->IncluderFiles) {
 
-         files += cmStrCat("  ", Quoted(item->FileName), '\n');
 
-       }
 
-       LogError(
 
-         GenT::UIC,
 
-         cmStrCat(
 
-           "The source files\n", files, "contain the same include string ",
 
-           Quoted(includeString),
 
-           ", but\nthe uic file would be generated from different "
 
-           "user interface files\n  ",
 
-           Quoted(uiFileHandle->FileName), " and\n  ",
 
-           Quoted(handle->SourceFile->FileName),
 
-           ".\nConsider to\n"
 
-           "  - add a directory prefix to a \"ui_<NAME>.h\" include "
 
-           "(e.g \"sub/ui_<NAME>.h\")\n"
 
-           "  - rename the <NAME>.ui file(s) and adjust the \"ui_<NAME>.h\" "
 
-           "include(s)\n"));
 
-       return false;
 
-     }
 
-     // Add includer file to existing mapping
 
-     handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
 
-   } else {
 
-     // New mapping handle
 
-     MappingHandleT handle = std::make_shared<MappingT>();
 
-     handle->IncludeString = includeString;
 
-     handle->IncluderFiles.emplace_back(std::move(includerFileHandle));
 
-     handle->SourceFile = std::move(uiFileHandle);
 
-     handle->OutputFile = Gen()->AbsoluteIncludePath(includeString);
 
-     // Register mapping
 
-     Includes.emplace(includeString, std::move(handle));
 
-   }
 
-   return true;
 
- }
 
- cmQtAutoMocUic::SourceFileHandleT
 
- cmQtAutoMocUic::JobEvaluateT::UicFindIncludedUi(
 
-   std::string const& sourceFile, std::string const& sourceDir,
 
-   IncludeKeyT const& incKey) const
 
- {
 
-   std::string searchFileName = cmStrCat(incKey.Base, ".ui");
 
-   // Collect search paths list
 
-   std::vector<std::string> testFiles;
 
-   {
 
-     auto& searchPaths = UicConst().SearchPaths;
 
-     testFiles.reserve((searchPaths.size() + 1) * 2);
 
-     // Vicinity of the source
 
-     testFiles.emplace_back(sourceDir + searchFileName);
 
-     if (!incKey.Dir.empty()) {
 
-       testFiles.emplace_back(cmStrCat(sourceDir, incKey.Dir, searchFileName));
 
-     }
 
-     // AUTOUIC search paths
 
-     if (!searchPaths.empty()) {
 
-       for (std::string const& sPath : searchPaths) {
 
-         testFiles.emplace_back(cmStrCat(sPath, '/', searchFileName));
 
-       }
 
-       if (!incKey.Dir.empty()) {
 
-         for (std::string const& sPath : searchPaths) {
 
-           testFiles.emplace_back(
 
-             cmStrCat(sPath, '/', incKey.Dir, searchFileName));
 
-         }
 
-       }
 
-     }
 
-   }
 
-   // Search for the .ui file!
 
-   for (std::string const& testFile : testFiles) {
 
-     cmFileTime fileTime;
 
-     if (fileTime.Load(testFile)) {
 
-       // .ui file found in files system!
 
-       std::string realPath = cmSystemTools::GetRealPath(testFile);
 
-       // Get or create .ui file handle
 
-       SourceFileHandleT& handle = Gen()->UicEval().UiFiles[realPath];
 
-       if (!handle) {
 
-         // The file wasn't registered, yet
 
-         handle = std::make_shared<SourceFileT>(realPath);
 
-         handle->FileTime = fileTime;
 
-       }
 
-       return handle;
 
-     }
 
-   }
 
-   // Log error
 
-   {
 
-     std::string files;
 
-     for (std::string const& testFile : testFiles) {
 
-       files += cmStrCat("  ", Quoted(testFile), '\n');
 
-     }
 
-     LogFileError(
 
-       GenT::UIC, sourceFile,
 
-       cmStrCat("The file includes the uic file ", Quoted(incKey.Key),
 
-                ",\nbut the user interface file ", Quoted(searchFileName),
 
-                "\ncould not be found in the following locations\n", files));
 
-   }
 
-   return SourceFileHandleT();
 
- }
 
- void cmQtAutoMocUic::JobGenerateT::Process()
 
- {
 
-   // Add moc compile jobs
 
-   if (MocConst().Enabled) {
 
-     for (auto const& pair : MocEval().HeaderMappings) {
 
-       // Register if this mapping is a candidate for mocs_compilation.cpp
 
-       bool const compFile = pair.second->IncludeString.empty();
 
-       if (compFile) {
 
-         MocEval().CompFiles.emplace_back(pair.second->SourceFile->BuildPath);
 
-       }
 
-       if (!MocGenerate(pair.second, compFile)) {
 
-         return;
 
-       }
 
-     }
 
-     for (auto const& pair : MocEval().SourceMappings) {
 
-       if (!MocGenerate(pair.second, false)) {
 
-         return;
 
-       }
 
-     }
 
-     // Add mocs compilations job on demand
 
-     Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
 
-   }
 
-   // Add uic compile jobs
 
-   if (UicConst().Enabled) {
 
-     for (auto const& pair : Gen()->UicEval().Includes) {
 
-       if (!UicGenerate(pair.second)) {
 
-         return;
 
-       }
 
-     }
 
-   }
 
-   // Add finish job
 
-   Gen()->WorkerPool().EmplaceJob<JobFinishT>();
 
- }
 
- bool cmQtAutoMocUic::JobGenerateT::MocGenerate(MappingHandleT const& mapping,
 
-                                                bool compFile) const
 
- {
 
-   std::unique_ptr<std::string> reason;
 
-   if (Log().Verbose()) {
 
-     reason = cm::make_unique<std::string>();
 
-   }
 
-   if (MocUpdate(*mapping, reason.get())) {
 
-     // Create the parent directory
 
-     if (!MakeParentDirectory(mapping->OutputFile)) {
 
-       LogFileError(GenT::MOC, mapping->OutputFile,
 
-                    "Could not create parent directory.");
 
-       return false;
 
-     }
 
-     // Add moc job
 
-     Gen()->WorkerPool().EmplaceJob<JobMocT>(mapping, std::move(reason));
 
-     // Check if a moc job for a mocs_compilation.cpp entry was generated
 
-     if (compFile) {
 
-       MocEval().CompUpdated = true;
 
-     }
 
-   }
 
-   return true;
 
- }
 
- bool cmQtAutoMocUic::JobGenerateT::MocUpdate(MappingT const& mapping,
 
-                                              std::string* reason) const
 
- {
 
-   std::string const& sourceFile = mapping.SourceFile->FileName;
 
-   std::string const& outputFile = mapping.OutputFile;
 
-   // Test if the output file exists
 
-   cmFileTime outputFileTime;
 
-   if (!outputFileTime.Load(outputFile)) {
 
-     if (reason != nullptr) {
 
-       *reason =
 
-         cmStrCat("Generating ", Quoted(outputFile),
 
-                  ", because it doesn't exist, from ", Quoted(sourceFile));
 
-     }
 
-     return true;
 
-   }
 
-   // Test if any setting changed
 
-   if (MocConst().SettingsChanged) {
 
-     if (reason != nullptr) {
 
-       *reason = cmStrCat("Generating ", Quoted(outputFile),
 
-                          ", because the uic settings changed, from ",
 
-                          Quoted(sourceFile));
 
-     }
 
-     return true;
 
-   }
 
-   // Test if the source file is newer
 
-   if (outputFileTime.Older(mapping.SourceFile->FileTime)) {
 
-     if (reason != nullptr) {
 
-       *reason = cmStrCat("Generating ", Quoted(outputFile),
 
-                          ", because it's older than its source file, from ",
 
-                          Quoted(sourceFile));
 
-     }
 
-     return true;
 
-   }
 
-   // Test if the moc_predefs file is newer
 
-   if (!MocConst().PredefsFileAbs.empty()) {
 
-     if (outputFileTime.Older(MocEval().PredefsTime)) {
 
-       if (reason != nullptr) {
 
-         *reason = cmStrCat(
 
-           "Generating ", Quoted(outputFile), ", because it's older than ",
 
-           Quoted(MocConst().PredefsFileAbs), ", from ", Quoted(sourceFile));
 
-       }
 
-       return true;
 
-     }
 
-   }
 
-   // Test if the moc executable is newer
 
-   if (outputFileTime.Older(MocConst().ExecutableTime)) {
 
-     if (reason != nullptr) {
 
-       *reason = cmStrCat("Generating ", Quoted(outputFile),
 
-                          ", because it's older than the moc executable, from ",
 
-                          Quoted(sourceFile));
 
-     }
 
-     return true;
 
-   }
 
-   // Test if a dependency file is newer
 
-   {
 
-     // Check dependency timestamps
 
-     std::string const sourceDir = SubDirPrefix(sourceFile);
 
-     for (std::string const& dep : mapping.SourceFile->ParseData->Moc.Depends) {
 
-       // Find dependency file
 
-       auto const depMatch = MocFindDependency(sourceDir, dep);
 
-       if (depMatch.first.empty()) {
 
-         Log().WarningFile(GenT::MOC, sourceFile,
 
-                           "Could not find dependency file " + Quoted(dep));
 
-         continue;
 
-       }
 
-       // Test if dependency file is older
 
-       if (outputFileTime.Older(depMatch.second)) {
 
-         if (reason != nullptr) {
 
-           *reason =
 
-             cmStrCat("Generating ", Quoted(outputFile),
 
-                      ", because it's older than its dependency file ",
 
-                      Quoted(depMatch.first), ", from ", Quoted(sourceFile));
 
-         }
 
-         return true;
 
-       }
 
-     }
 
-   }
 
-   return false;
 
- }
 
- std::pair<std::string, cmFileTime>
 
- cmQtAutoMocUic::JobGenerateT::MocFindDependency(
 
-   std::string const& sourceDir, std::string const& includeString) const
 
- {
 
-   using ResPair = std::pair<std::string, cmFileTime>;
 
-   // Search in vicinity of the source
 
-   {
 
-     ResPair res{ sourceDir + includeString, {} };
 
-     if (res.second.Load(res.first)) {
 
-       return res;
 
-     }
 
-   }
 
-   // Search in include directories
 
-   for (std::string const& includePath : MocConst().IncludePaths) {
 
-     ResPair res{ cmStrCat(includePath, '/', includeString), {} };
 
-     if (res.second.Load(res.first)) {
 
-       return res;
 
-     }
 
-   }
 
-   // Return empty
 
-   return ResPair();
 
- }
 
- bool cmQtAutoMocUic::JobGenerateT::UicGenerate(
 
-   MappingHandleT const& mapping) const
 
- {
 
-   std::unique_ptr<std::string> reason;
 
-   if (Log().Verbose()) {
 
-     reason = cm::make_unique<std::string>();
 
-   }
 
-   if (UicUpdate(*mapping, reason.get())) {
 
-     // Create the parent directory
 
-     if (!MakeParentDirectory(mapping->OutputFile)) {
 
-       LogFileError(GenT::UIC, mapping->OutputFile,
 
-                    "Could not create parent directory.");
 
-       return false;
 
-     }
 
-     // Add uic job
 
-     Gen()->WorkerPool().EmplaceJob<JobUicT>(mapping, std::move(reason));
 
-   }
 
-   return true;
 
- }
 
- bool cmQtAutoMocUic::JobGenerateT::UicUpdate(MappingT const& mapping,
 
-                                              std::string* reason) const
 
- {
 
-   std::string const& sourceFile = mapping.SourceFile->FileName;
 
-   std::string const& outputFile = mapping.OutputFile;
 
-   // Test if the build file exists
 
-   cmFileTime outputFileTime;
 
-   if (!outputFileTime.Load(outputFile)) {
 
-     if (reason != nullptr) {
 
-       *reason =
 
-         cmStrCat("Generating ", Quoted(outputFile),
 
-                  ", because it doesn't exist, from ", Quoted(sourceFile));
 
-     }
 
-     return true;
 
-   }
 
-   // Test if the uic settings changed
 
-   if (UicConst().SettingsChanged) {
 
-     if (reason != nullptr) {
 
-       *reason = cmStrCat("Generating ", Quoted(outputFile),
 
-                          ", because the uic settings changed, from ",
 
-                          Quoted(sourceFile));
 
-     }
 
-     return true;
 
-   }
 
-   // Test if the source file is newer
 
-   if (outputFileTime.Older(mapping.SourceFile->FileTime)) {
 
-     if (reason != nullptr) {
 
-       *reason = cmStrCat("Generating ", Quoted(outputFile),
 
-                          " because it's older than the source file ",
 
-                          Quoted(sourceFile));
 
-     }
 
-     return true;
 
-   }
 
-   // Test if the uic executable is newer
 
-   if (outputFileTime.Older(UicConst().ExecutableTime)) {
 
-     if (reason != nullptr) {
 
-       *reason = cmStrCat("Generating ", Quoted(outputFile),
 
-                          ", because it's older than the uic executable, from ",
 
-                          Quoted(sourceFile));
 
-     }
 
-     return true;
 
-   }
 
-   return false;
 
- }
 
- void cmQtAutoMocUic::JobMocT::Process()
 
- {
 
-   std::string const& sourceFile = Mapping->SourceFile->FileName;
 
-   std::string const& outputFile = Mapping->OutputFile;
 
-   // Compose moc command
 
-   std::vector<std::string> cmd;
 
-   cmd.push_back(MocConst().Executable);
 
-   // Add options
 
-   cmAppend(cmd, MocConst().AllOptions);
 
-   // Add predefs include
 
-   if (!MocConst().PredefsFileAbs.empty()) {
 
-     cmd.emplace_back("--include");
 
-     cmd.push_back(MocConst().PredefsFileAbs);
 
-   }
 
-   cmd.emplace_back("-o");
 
-   cmd.push_back(outputFile);
 
-   cmd.push_back(sourceFile);
 
-   // Execute moc command
 
-   cmWorkerPool::ProcessResultT result;
 
-   if (RunProcess(GenT::MOC, result, cmd, Reason.get())) {
 
-     // Moc command success. Print moc output.
 
-     if (!result.StdOut.empty()) {
 
-       Log().Info(GenT::MOC, result.StdOut);
 
-     }
 
-   } else {
 
-     // Moc command failed
 
-     std::string includers;
 
-     if (!Mapping->IncluderFiles.empty()) {
 
-       includers = "included by\n";
 
-       for (auto const& item : Mapping->IncluderFiles) {
 
-         includers += cmStrCat("  ", Quoted(item->FileName), '\n');
 
-       }
 
-     }
 
-     LogCommandError(GenT::MOC,
 
-                     cmStrCat("The moc process failed to compile\n  ",
 
-                              Quoted(sourceFile), "\ninto\n  ",
 
-                              Quoted(outputFile), '\n', includers,
 
-                              result.ErrorMessage),
 
-                     cmd, result.StdOut);
 
-   }
 
- }
 
- void cmQtAutoMocUic::JobUicT::Process()
 
- {
 
-   std::string const& sourceFile = Mapping->SourceFile->FileName;
 
-   std::string const& outputFile = Mapping->OutputFile;
 
-   // Compose uic command
 
-   std::vector<std::string> cmd;
 
-   cmd.push_back(UicConst().Executable);
 
-   {
 
-     std::vector<std::string> allOpts = UicConst().TargetOptions;
 
-     auto optionIt = UicConst().Options.find(sourceFile);
 
-     if (optionIt != UicConst().Options.end()) {
 
-       UicMergeOptions(allOpts, optionIt->second,
 
-                       (BaseConst().QtVersionMajor == 5));
 
-     }
 
-     cmAppend(cmd, allOpts);
 
-   }
 
-   cmd.emplace_back("-o");
 
-   cmd.emplace_back(outputFile);
 
-   cmd.emplace_back(sourceFile);
 
-   cmWorkerPool::ProcessResultT result;
 
-   if (RunProcess(GenT::UIC, result, cmd, Reason.get())) {
 
-     // Uic command success
 
-     // Print uic output
 
-     if (!result.StdOut.empty()) {
 
-       Log().Info(GenT::UIC, result.StdOut);
 
-     }
 
-   } else {
 
-     // Uic command failed
 
-     std::string includers;
 
-     for (auto const& item : Mapping->IncluderFiles) {
 
-       includers += cmStrCat("  ", Quoted(item->FileName), '\n');
 
-     }
 
-     LogCommandError(GenT::UIC,
 
-                     cmStrCat("The uic process failed to compile\n  ",
 
-                              Quoted(sourceFile), "\ninto\n  ",
 
-                              Quoted(outputFile), "\nincluded by\n", includers,
 
-                              result.ErrorMessage),
 
-                     cmd, result.StdOut);
 
-   }
 
- }
 
- void cmQtAutoMocUic::JobMocsCompilationT::Process()
 
- {
 
-   // Compose mocs compilation file content
 
-   std::string content =
 
-     "// This file is autogenerated. Changes will be overwritten.\n";
 
-   if (MocEval().CompFiles.empty()) {
 
-     // Placeholder content
 
-     content += "// No files found that require moc or the moc files are "
 
-                "included\n"
 
-                "enum some_compilers { need_more_than_nothing };\n";
 
-   } else {
 
-     // Valid content
 
-     const bool mc = BaseConst().MultiConfig;
 
-     cm::string_view const wrapFront = mc ? "#include <" : "#include \"";
 
-     cm::string_view const wrapBack = mc ? ">\n" : "\"\n";
 
-     content += cmWrap(wrapFront, MocEval().CompFiles, wrapBack, "");
 
-   }
 
-   std::string const& compAbs = MocConst().CompFileAbs;
 
-   if (cmQtAutoGenerator::FileDiffers(compAbs, content)) {
 
-     // Actually write mocs compilation file
 
-     if (Log().Verbose()) {
 
-       Log().Info(GenT::MOC, "Generating MOC compilation " + compAbs);
 
-     }
 
-     if (!FileWrite(compAbs, content)) {
 
-       LogFileError(GenT::MOC, compAbs,
 
-                    "mocs compilation file writing failed.");
 
-     }
 
-   } else if (MocEval().CompUpdated) {
 
-     // Only touch mocs compilation file
 
-     if (Log().Verbose()) {
 
-       Log().Info(GenT::MOC, "Touching mocs compilation " + compAbs);
 
-     }
 
-     if (!cmSystemTools::Touch(compAbs, false)) {
 
-       LogFileError(GenT::MOC, compAbs,
 
-                    "mocs compilation file touching failed.");
 
-     }
 
-   }
 
- }
 
- void cmQtAutoMocUic::JobFinishT::Process()
 
- {
 
-   Gen()->AbortSuccess();
 
- }
 
- cmQtAutoMocUic::cmQtAutoMocUic() = default;
 
- cmQtAutoMocUic::~cmQtAutoMocUic() = default;
 
- bool cmQtAutoMocUic::Init(cmMakefile* makefile)
 
- {
 
-   // Utility lambdas
 
-   auto InfoGet = [makefile](cm::string_view key) {
 
-     return makefile->GetSafeDefinition(std::string(key));
 
-   };
 
-   auto InfoGetBool = [makefile](cm::string_view key) {
 
-     return makefile->IsOn(std::string(key));
 
-   };
 
-   auto InfoGetList =
 
-     [makefile](cm::string_view key) -> std::vector<std::string> {
 
-     return cmExpandedList(makefile->GetSafeDefinition(std::string(key)));
 
-   };
 
-   auto InfoGetLists =
 
-     [makefile](cm::string_view key) -> std::vector<std::vector<std::string>> {
 
-     std::vector<std::vector<std::string>> lists;
 
-     {
 
-       std::string const value = makefile->GetSafeDefinition(std::string(key));
 
-       std::string::size_type pos = 0;
 
-       while (pos < value.size()) {
 
-         std::string::size_type next = value.find(ListSep, pos);
 
-         std::string::size_type length =
 
-           (next != std::string::npos) ? next - pos : value.size() - pos;
 
-         // Remove enclosing braces
 
-         if (length >= 2) {
 
-           std::string::const_iterator itBeg = value.begin() + (pos + 1);
 
-           std::string::const_iterator itEnd = itBeg + (length - 2);
 
-           lists.emplace_back(cmExpandedList(std::string(itBeg, itEnd)));
 
-         }
 
-         pos += length;
 
-         pos += ListSep.size();
 
-       }
 
-     }
 
-     return lists;
 
-   };
 
-   auto InfoGetConfig = [makefile, this](cm::string_view key) -> std::string {
 
-     if (const char* valueConf =
 
-           makefile->GetDefinition(cmStrCat(key, '_', InfoConfig()))) {
 
-       return std::string(valueConf);
 
-     }
 
-     return makefile->GetSafeDefinition(std::string(key));
 
-   };
 
-   auto InfoGetConfigList =
 
-     [&InfoGetConfig](cm::string_view key) -> std::vector<std::string> {
 
-     return cmExpandedList(InfoGetConfig(key));
 
-   };
 
-   auto LogInfoError = [this](cm::string_view msg) -> bool {
 
-     this->Log().Error(GenT::GEN,
 
-                       cmStrCat("In ", Quoted(this->InfoFile()), ":\n", msg));
 
-     return false;
 
-   };
 
-   auto MatchSizes = [&LogInfoError](cm::string_view keyA, cm::string_view keyB,
 
-                                     std::size_t sizeA,
 
-                                     std::size_t sizeB) -> bool {
 
-     if (sizeA == sizeB) {
 
-       return true;
 
-     }
 
-     return LogInfoError(cmStrCat("Lists sizes mismatch ", keyA, '(', sizeA,
 
-                                  ") ", keyB, '(', sizeB, ')'));
 
-   };
 
-   // -- Read info file
 
-   if (!makefile->ReadListFile(InfoFile())) {
 
-     return LogInfoError("File processing failed");
 
-   }
 
-   // -- Meta
 
-   Logger_.RaiseVerbosity(InfoGet("AM_VERBOSITY"));
 
-   BaseConst_.MultiConfig = InfoGetBool("AM_MULTI_CONFIG");
 
-   {
 
-     unsigned long num = 1;
 
-     if (cmStrToULong(InfoGet("AM_PARALLEL"), &num)) {
 
-       num = std::max<unsigned long>(num, 1);
 
-       num = std::min<unsigned long>(num, ParallelMax);
 
-     }
 
-     WorkerPool_.SetThreadCount(static_cast<unsigned int>(num));
 
-   }
 
-   BaseConst_.HeaderExtensions =
 
-     makefile->GetCMakeInstance()->GetHeaderExtensions();
 
-   // - Files and directories
 
-   BaseConst_.IncludeProjectDirsBefore =
 
-     InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
 
-   BaseConst_.ProjectSourceDir = InfoGet("AM_CMAKE_SOURCE_DIR");
 
-   BaseConst_.ProjectBinaryDir = InfoGet("AM_CMAKE_BINARY_DIR");
 
-   BaseConst_.CurrentSourceDir = InfoGet("AM_CMAKE_CURRENT_SOURCE_DIR");
 
-   BaseConst_.CurrentBinaryDir = InfoGet("AM_CMAKE_CURRENT_BINARY_DIR");
 
-   BaseConst_.AutogenBuildDir = InfoGet("AM_BUILD_DIR");
 
-   if (BaseConst_.AutogenBuildDir.empty()) {
 
-     return LogInfoError("Autogen build directory missing.");
 
-   }
 
-   BaseConst_.AutogenIncludeDir = InfoGetConfig("AM_INCLUDE_DIR");
 
-   if (BaseConst_.AutogenIncludeDir.empty()) {
 
-     return LogInfoError("Autogen include directory missing.");
 
-   }
 
-   BaseConst_.CMakeExecutable = InfoGetConfig("AM_CMAKE_EXECUTABLE");
 
-   if (BaseConst_.CMakeExecutable.empty()) {
 
-     return LogInfoError("CMake executable file name missing.");
 
-   }
 
-   if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) {
 
-     return LogInfoError(cmStrCat("The CMake executable ",
 
-                                  Quoted(BaseConst_.CMakeExecutable),
 
-                                  " does not exist."));
 
-   }
 
-   BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE");
 
-   if (BaseConst_.ParseCacheFile.empty()) {
 
-     return LogInfoError("Parse cache file name missing.");
 
-   }
 
-   // - Settings file
 
-   SettingsFile_ = InfoGetConfig("AM_SETTINGS_FILE");
 
-   if (SettingsFile_.empty()) {
 
-     return LogInfoError("Settings file name missing.");
 
-   }
 
-   // - Qt environment
 
-   {
 
-     unsigned long qtv = BaseConst_.QtVersionMajor;
 
-     if (cmStrToULong(InfoGet("AM_QT_VERSION_MAJOR"), &qtv)) {
 
-       BaseConst_.QtVersionMajor = static_cast<unsigned int>(qtv);
 
-     }
 
-   }
 
-   // - Moc
 
-   MocConst_.Executable = InfoGet("AM_QT_MOC_EXECUTABLE");
 
-   if (!MocConst().Executable.empty()) {
 
-     MocConst_.Enabled = true;
 
-     // Load the executable file time
 
-     if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
 
-       return LogInfoError(cmStrCat("The moc executable ",
 
-                                    Quoted(MocConst_.Executable),
 
-                                    " does not exist."));
 
-     }
 
-     for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) {
 
-       MocConst_.SkipList.insert(std::move(sfl));
 
-     }
 
-     MocConst_.Definitions = InfoGetConfigList("AM_MOC_DEFINITIONS");
 
-     MocConst_.IncludePaths = InfoGetConfigList("AM_MOC_INCLUDES");
 
-     MocConst_.Options = InfoGetList("AM_MOC_OPTIONS");
 
-     MocConst_.RelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE");
 
-     for (std::string const& item : InfoGetList("AM_MOC_MACRO_NAMES")) {
 
-       MocConst_.MacroFilters.emplace_back(
 
-         item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
 
-     }
 
-     {
 
-       auto addFilter = [this, &LogInfoError](std::string const& key,
 
-                                              std::string const& exp) -> bool {
 
-         auto filterErr = [&LogInfoError, &key,
 
-                           &exp](cm::string_view err) -> bool {
 
-           return LogInfoError(cmStrCat("AUTOMOC_DEPEND_FILTERS: ", err, '\n',
 
-                                        "  Key: ", Quoted(key), '\n',
 
-                                        "  Exp: ", Quoted(exp), '\n'));
 
-         };
 
-         if (key.empty()) {
 
-           return filterErr("Key is empty");
 
-         }
 
-         if (exp.empty()) {
 
-           return filterErr("Regular expression is empty");
 
-         }
 
-         this->MocConst_.DependFilters.emplace_back(key, exp);
 
-         if (!this->MocConst_.DependFilters.back().Exp.is_valid()) {
 
-           return filterErr("Regular expression compiling failed");
 
-         }
 
-         return true;
 
-       };
 
-       // Insert default filter for Q_PLUGIN_METADATA
 
-       if (BaseConst().QtVersionMajor != 4) {
 
-         if (!addFilter("Q_PLUGIN_METADATA",
 
-                        "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
 
-                        "[^\\)]*FILE[ \t]*\"([^\"]+)\"")) {
 
-           return false;
 
-         }
 
-       }
 
-       // Insert user defined dependency filters
 
-       std::vector<std::string> flts = InfoGetList("AM_MOC_DEPEND_FILTERS");
 
-       if ((flts.size() % 2) != 0) {
 
-         return LogInfoError(
 
-           "AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2");
 
-       }
 
-       for (auto itC = flts.begin(), itE = flts.end(); itC != itE; itC += 2) {
 
-         if (!addFilter(*itC, *(itC + 1))) {
 
-           return false;
 
-         }
 
-       }
 
-     }
 
-     MocConst_.PredefsCmd = InfoGetList("AM_MOC_PREDEFS_CMD");
 
-   }
 
-   // - Uic
 
-   UicConst_.Executable = InfoGet("AM_QT_UIC_EXECUTABLE");
 
-   if (!UicConst().Executable.empty()) {
 
-     UicConst_.Enabled = true;
 
-     // Load the executable file time
 
-     if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
 
-       return LogInfoError(cmStrCat("The uic executable ",
 
-                                    Quoted(UicConst_.Executable),
 
-                                    " does not exist."));
 
-     }
 
-     for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) {
 
-       UicConst_.SkipList.insert(std::move(sfl));
 
-     }
 
-     UicConst_.SearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS");
 
-     UicConst_.TargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS");
 
-     {
 
-       cm::string_view const keyFiles = "AM_UIC_OPTIONS_FILES";
 
-       cm::string_view const keyOpts = "AM_UIC_OPTIONS_OPTIONS";
 
-       auto sources = InfoGetList(keyFiles);
 
-       auto options = InfoGetLists(keyOpts);
 
-       if (!MatchSizes(keyFiles, keyOpts, sources.size(), options.size())) {
 
-         return false;
 
-       }
 
-       auto fitEnd = sources.cend();
 
-       auto fit = sources.begin();
 
-       auto oit = options.begin();
 
-       while (fit != fitEnd) {
 
-         UicConst_.Options[*fit] = std::move(*oit);
 
-         ++fit;
 
-         ++oit;
 
-       }
 
-     }
 
-   }
 
-   // - Headers and sources
 
-   {
 
-     auto makeSource =
 
-       [&LogInfoError](std::string const& fileName,
 
-                       std::string const& fileFlags) -> SourceFileHandleT {
 
-       if (fileFlags.size() != 2) {
 
-         LogInfoError("Invalid file flags string size");
 
-         return SourceFileHandleT();
 
-       }
 
-       cmFileTime fileTime;
 
-       if (!fileTime.Load(fileName)) {
 
-         LogInfoError("The source file " + cmQtAutoGen::Quoted(fileName) +
 
-                      " does not exist.");
 
-         return SourceFileHandleT();
 
-       }
 
-       SourceFileHandleT sfh = std::make_shared<SourceFileT>(fileName);
 
-       sfh->FileTime = fileTime;
 
-       sfh->Moc = (fileFlags[0] == 'M');
 
-       sfh->Uic = (fileFlags[1] == 'U');
 
-       return sfh;
 
-     };
 
-     // Headers
 
-     {
 
-       // Get file lists
 
-       cm::string_view const keyFiles = "AM_HEADERS";
 
-       cm::string_view const keyFlags = "AM_HEADERS_FLAGS";
 
-       std::vector<std::string> files = InfoGetList(keyFiles);
 
-       std::vector<std::string> flags = InfoGetList(keyFlags);
 
-       std::vector<std::string> builds;
 
-       if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
 
-         return false;
 
-       }
 
-       if (MocConst().Enabled) {
 
-         cm::string_view const keyPaths = "AM_HEADERS_BUILD_PATHS";
 
-         builds = InfoGetList(keyPaths);
 
-         if (!MatchSizes(keyFiles, keyPaths, files.size(), builds.size())) {
 
-           return false;
 
-         }
 
-       }
 
-       // Process file lists
 
-       for (std::size_t ii = 0; ii != files.size(); ++ii) {
 
-         std::string& fileName(files[ii]);
 
-         SourceFileHandleT sfh = makeSource(fileName, flags[ii]);
 
-         if (!sfh) {
 
-           return false;
 
-         }
 
-         if (MocConst().Enabled) {
 
-           sfh->BuildPath = std::move(builds[ii]);
 
-           if (sfh->BuildPath.empty()) {
 
-             Log().ErrorFile(GenT::GEN, this->InfoFile(),
 
-                             "Header file build path is empty");
 
-             return false;
 
-           }
 
-         }
 
-         BaseEval().Headers.emplace(std::move(fileName), std::move(sfh));
 
-       }
 
-     }
 
-     // Sources
 
-     {
 
-       cm::string_view const keyFiles = "AM_SOURCES";
 
-       cm::string_view const keyFlags = "AM_SOURCES_FLAGS";
 
-       std::vector<std::string> files = InfoGetList(keyFiles);
 
-       std::vector<std::string> flags = InfoGetList(keyFlags);
 
-       if (!MatchSizes(keyFiles, keyFlags, files.size(), flags.size())) {
 
-         return false;
 
-       }
 
-       // Process file lists
 
-       for (std::size_t ii = 0; ii != files.size(); ++ii) {
 
-         std::string& fileName(files[ii]);
 
-         SourceFileHandleT sfh = makeSource(fileName, flags[ii]);
 
-         if (!sfh) {
 
-           return false;
 
-         }
 
-         BaseEval().Sources.emplace(std::move(fileName), std::move(sfh));
 
-       }
 
-     }
 
-   }
 
-   // Init derived information
 
-   // ------------------------
 
-   // Moc variables
 
-   if (MocConst().Enabled) {
 
-     // Mocs compilation file
 
-     MocConst_.CompFileAbs = AbsoluteBuildPath("mocs_compilation.cpp");
 
-     // Moc predefs file
 
-     if (!MocConst_.PredefsCmd.empty()) {
 
-       if (BaseConst_.MultiConfig) {
 
-         MocConst_.PredefsFileRel =
 
-           cmStrCat("moc_predefs_", InfoConfig(), ".h");
 
-       } else {
 
-         MocConst_.PredefsFileRel = "moc_predefs.h";
 
-       }
 
-       MocConst_.PredefsFileAbs = AbsoluteBuildPath(MocConst().PredefsFileRel);
 
-     }
 
-     // Sort include directories on demand
 
-     if (BaseConst().IncludeProjectDirsBefore) {
 
-       // Move strings to temporary list
 
-       std::list<std::string> includes(MocConst().IncludePaths.begin(),
 
-                                       MocConst().IncludePaths.end());
 
-       MocConst_.IncludePaths.clear();
 
-       MocConst_.IncludePaths.reserve(includes.size());
 
-       // Append project directories only
 
-       {
 
-         std::initializer_list<cm::string_view> const movePaths = {
 
-           BaseConst().ProjectBinaryDir, BaseConst().ProjectSourceDir
 
-         };
 
-         for (cm::string_view const& ppath : movePaths) {
 
-           auto it = includes.begin();
 
-           while (it != includes.end()) {
 
-             std::string const& path = *it;
 
-             if (cmHasPrefix(path, ppath)) {
 
-               MocConst_.IncludePaths.push_back(path);
 
-               it = includes.erase(it);
 
-             } else {
 
-               ++it;
 
-             }
 
-           }
 
-         }
 
-       }
 
-       // Append remaining directories
 
-       MocConst_.IncludePaths.insert(MocConst_.IncludePaths.end(),
 
-                                     includes.begin(), includes.end());
 
-     }
 
-     // Compose moc includes list
 
-     {
 
-       std::set<std::string> frameworkPaths;
 
-       for (std::string const& path : MocConst().IncludePaths) {
 
-         MocConst_.Includes.push_back("-I" + path);
 
-         // Extract framework path
 
-         if (cmHasLiteralSuffix(path, ".framework/Headers")) {
 
-           // Go up twice to get to the framework root
 
-           std::vector<std::string> pathComponents;
 
-           cmSystemTools::SplitPath(path, pathComponents);
 
-           frameworkPaths.emplace(cmSystemTools::JoinPath(
 
-             pathComponents.begin(), pathComponents.end() - 2));
 
-         }
 
-       }
 
-       // Append framework includes
 
-       for (std::string const& path : frameworkPaths) {
 
-         MocConst_.Includes.emplace_back("-F");
 
-         MocConst_.Includes.push_back(path);
 
-       }
 
-     }
 
-     // Setup single list with all options
 
-     {
 
-       // Add includes
 
-       MocConst_.AllOptions.insert(MocConst_.AllOptions.end(),
 
-                                   MocConst().Includes.begin(),
 
-                                   MocConst().Includes.end());
 
-       // Add definitions
 
-       for (std::string const& def : MocConst().Definitions) {
 
-         MocConst_.AllOptions.push_back("-D" + def);
 
-       }
 
-       // Add options
 
-       MocConst_.AllOptions.insert(MocConst_.AllOptions.end(),
 
-                                   MocConst().Options.begin(),
 
-                                   MocConst().Options.end());
 
-     }
 
-   }
 
-   return true;
 
- }
 
- template <class JOBTYPE>
 
- void cmQtAutoMocUic::CreateParseJobs(SourceFileMapT const& sourceMap)
 
- {
 
-   cmFileTime const parseCacheTime = BaseEval().ParseCacheTime;
 
-   ParseCacheT& parseCache = BaseEval().ParseCache;
 
-   for (auto& src : sourceMap) {
 
-     // Get or create the file parse data reference
 
-     ParseCacheT::GetOrInsertT cacheEntry = parseCache.GetOrInsert(src.first);
 
-     src.second->ParseData = std::move(cacheEntry.first);
 
-     // Create a parse job if the cache file was missing or is older
 
-     if (cacheEntry.second || src.second->FileTime.Newer(parseCacheTime)) {
 
-       BaseEval().ParseCacheChanged = true;
 
-       WorkerPool().EmplaceJob<JOBTYPE>(src.second);
 
-     }
 
-   }
 
- }
 
- void cmQtAutoMocUic::InitJobs()
 
- {
 
-   // Add moc_predefs.h job
 
-   if (MocConst().Enabled && !MocConst().PredefsCmd.empty()) {
 
-     WorkerPool().EmplaceJob<JobMocPredefsT>();
 
-   }
 
-   // Add header parse jobs
 
-   CreateParseJobs<JobParseHeaderT>(BaseEval().Headers);
 
-   // Add source parse jobs
 
-   CreateParseJobs<JobParseSourceT>(BaseEval().Sources);
 
-   // Add evaluate job
 
-   WorkerPool().EmplaceJob<JobEvaluateT>();
 
- }
 
- bool cmQtAutoMocUic::Process()
 
- {
 
-   SettingsFileRead();
 
-   ParseCacheRead();
 
-   if (!CreateDirectories()) {
 
-     return false;
 
-   }
 
-   InitJobs();
 
-   if (!WorkerPool_.Process(this)) {
 
-     return false;
 
-   }
 
-   if (JobError_) {
 
-     return false;
 
-   }
 
-   if (!ParseCacheWrite()) {
 
-     return false;
 
-   }
 
-   if (!SettingsFileWrite()) {
 
-     return false;
 
-   }
 
-   return true;
 
- }
 
- void cmQtAutoMocUic::SettingsFileRead()
 
- {
 
-   // Compose current settings strings
 
-   {
 
-     cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256);
 
-     auto cha = [&cryptoHash](cm::string_view value) {
 
-       cryptoHash.Append(value);
 
-       cryptoHash.Append(";");
 
-     };
 
-     if (MocConst_.Enabled) {
 
-       cryptoHash.Initialize();
 
-       cha(MocConst().Executable);
 
-       std::for_each(MocConst().AllOptions.begin(), MocConst().AllOptions.end(),
 
-                     cha);
 
-       cha(BaseConst().IncludeProjectDirsBefore ? "TRUE" : "FALSE");
 
-       std::for_each(MocConst().PredefsCmd.begin(), MocConst().PredefsCmd.end(),
 
-                     cha);
 
-       for (auto const& filter : MocConst().DependFilters) {
 
-         cha(filter.Key);
 
-       }
 
-       for (auto const& filter : MocConst().MacroFilters) {
 
-         cha(filter.Key);
 
-       }
 
-       SettingsStringMoc_ = cryptoHash.FinalizeHex();
 
-     }
 
-     if (UicConst().Enabled) {
 
-       cryptoHash.Initialize();
 
-       cha(UicConst().Executable);
 
-       std::for_each(UicConst().TargetOptions.begin(),
 
-                     UicConst().TargetOptions.end(), cha);
 
-       for (const auto& item : UicConst().Options) {
 
-         cha(item.first);
 
-         std::for_each(item.second.begin(), item.second.end(), cha);
 
-       }
 
-       SettingsStringUic_ = cryptoHash.FinalizeHex();
 
-     }
 
-   }
 
-   // Read old settings and compare
 
-   {
 
-     std::string content;
 
-     if (cmQtAutoGenerator::FileRead(content, SettingsFile_)) {
 
-       if (MocConst().Enabled) {
 
-         if (SettingsStringMoc_ != SettingsFind(content, "moc")) {
 
-           MocConst_.SettingsChanged = true;
 
-         }
 
-       }
 
-       if (UicConst().Enabled) {
 
-         if (SettingsStringUic_ != SettingsFind(content, "uic")) {
 
-           UicConst_.SettingsChanged = true;
 
-         }
 
-       }
 
-       // In case any setting changed remove the old settings file.
 
-       // This triggers a full rebuild on the next run if the current
 
-       // build is aborted before writing the current settings in the end.
 
-       if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
 
-         cmSystemTools::RemoveFile(SettingsFile_);
 
-       }
 
-     } else {
 
-       // Settings file read failed
 
-       if (MocConst().Enabled) {
 
-         MocConst_.SettingsChanged = true;
 
-       }
 
-       if (UicConst().Enabled) {
 
-         UicConst_.SettingsChanged = true;
 
-       }
 
-     }
 
-   }
 
- }
 
- bool cmQtAutoMocUic::SettingsFileWrite()
 
- {
 
-   // Only write if any setting changed
 
-   if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
 
-     if (Log().Verbose()) {
 
-       Log().Info(GenT::GEN, "Writing settings file " + Quoted(SettingsFile_));
 
-     }
 
-     // Compose settings file content
 
-     std::string content;
 
-     {
 
-       auto SettingAppend = [&content](cm::string_view key,
 
-                                       cm::string_view value) {
 
-         if (!value.empty()) {
 
-           content += cmStrCat(key, ':', value, '\n');
 
-         }
 
-       };
 
-       SettingAppend("moc", SettingsStringMoc_);
 
-       SettingAppend("uic", SettingsStringUic_);
 
-     }
 
-     // Write settings file
 
-     std::string error;
 
-     if (!cmQtAutoGenerator::FileWrite(SettingsFile_, content, &error)) {
 
-       Log().ErrorFile(GenT::GEN, SettingsFile_,
 
-                       "Settings file writing failed. " + error);
 
-       // Remove old settings file to trigger a full rebuild on the next run
 
-       cmSystemTools::RemoveFile(SettingsFile_);
 
-       return false;
 
-     }
 
-   }
 
-   return true;
 
- }
 
- void cmQtAutoMocUic::ParseCacheRead()
 
- {
 
-   cm::string_view reason;
 
-   // Don't read the cache if it is invalid
 
-   if (!BaseEval().ParseCacheTime.Load(BaseConst().ParseCacheFile)) {
 
-     reason = "Refreshing parse cache because it doesn't exist.";
 
-   } else if (MocConst().SettingsChanged || UicConst().SettingsChanged) {
 
-     reason = "Refreshing parse cache because the settings changed.";
 
-   } else if (BaseEval().ParseCacheTime.Older(
 
-                BaseConst().CMakeExecutableTime)) {
 
-     reason =
 
-       "Refreshing parse cache because it is older than the CMake executable.";
 
-   }
 
-   if (!reason.empty()) {
 
-     // Don't read but refresh the complete parse cache
 
-     if (Log().Verbose()) {
 
-       Log().Info(GenT::GEN, reason);
 
-     }
 
-     BaseEval().ParseCacheChanged = true;
 
-   } else {
 
-     // Read parse cache
 
-     BaseEval().ParseCache.ReadFromFile(BaseConst().ParseCacheFile);
 
-   }
 
- }
 
- bool cmQtAutoMocUic::ParseCacheWrite()
 
- {
 
-   if (BaseEval().ParseCacheChanged) {
 
-     if (Log().Verbose()) {
 
-       Log().Info(GenT::GEN,
 
-                  "Writing parse cache file " +
 
-                    Quoted(BaseConst().ParseCacheFile));
 
-     }
 
-     if (!BaseEval().ParseCache.WriteToFile(BaseConst().ParseCacheFile)) {
 
-       Log().ErrorFile(GenT::GEN, BaseConst().ParseCacheFile,
 
-                       "Parse cache file writing failed.");
 
-       return false;
 
-     }
 
-   }
 
-   return true;
 
- }
 
- bool cmQtAutoMocUic::CreateDirectories()
 
- {
 
-   // Create AUTOGEN include directory
 
-   if (!cmSystemTools::MakeDirectory(BaseConst().AutogenIncludeDir)) {
 
-     Log().ErrorFile(GenT::GEN, BaseConst().AutogenIncludeDir,
 
-                     "Could not create directory.");
 
-     return false;
 
-   }
 
-   return true;
 
- }
 
- void cmQtAutoMocUic::Abort(bool error)
 
- {
 
-   if (error) {
 
-     JobError_.store(true);
 
-   }
 
-   WorkerPool_.Abort();
 
- }
 
- std::string cmQtAutoMocUic::AbsoluteBuildPath(
 
-   cm::string_view relativePath) const
 
- {
 
-   return cmStrCat(BaseConst().AutogenBuildDir, '/', relativePath);
 
- }
 
- std::string cmQtAutoMocUic::AbsoluteIncludePath(
 
-   cm::string_view relativePath) const
 
- {
 
-   return cmStrCat(BaseConst().AutogenIncludeDir, '/', relativePath);
 
- }
 
 
  |