/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerators.h"

#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
#include <algorithm>
#include <array>
#include <list>
#include <memory>
#include <sstream>
#include <string.h>
#include <utility>

#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFilePathChecksum.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmake.h"

#if defined(__APPLE__)
#include <unistd.h>
#endif

// -- Static variables

static const char* SettingsKeyMoc = "AM_MOC_SETTINGS_HASH";
static const char* SettingsKeyUic = "AM_UIC_SETTINGS_HASH";
static const char* SettingsKeyRcc = "AM_RCC_SETTINGS_HASH";

// -- Static functions

static std::string HeadLine(std::string const& title)
{
  std::string head = title;
  head += '\n';
  head.append(head.size() - 1, '-');
  head += '\n';
  return head;
}

static std::string QuotedCommand(std::vector<std::string> const& command)
{
  std::string res;
  for (std::string const& item : command) {
    if (!res.empty()) {
      res.push_back(' ');
    }
    std::string const cesc = cmQtAutoGen::Quoted(item);
    if (item.empty() || (cesc.size() > (item.size() + 2)) ||
        (cesc.find(' ') != std::string::npos)) {
      res += cesc;
    } else {
      res += item;
    }
  }
  return res;
}

static std::string SubDirPrefix(std::string const& fileName)
{
  std::string res(cmSystemTools::GetFilenamePath(fileName));
  if (!res.empty()) {
    res += '/';
  }
  return res;
}

static bool ReadFile(std::string& content, std::string const& filename,
                     std::string* error = nullptr)
{
  bool success = false;
  if (cmSystemTools::FileExists(filename)) {
    std::size_t const length = cmSystemTools::FileLength(filename);
    cmsys::ifstream ifs(filename.c_str(), (std::ios::in | std::ios::binary));
    if (ifs) {
      content.resize(length);
      ifs.read(&content.front(), content.size());
      if (ifs) {
        success = true;
      } else {
        content.clear();
        if (error != nullptr) {
          error->append("Reading from the file failed.");
        }
      }
    } else if (error != nullptr) {
      error->append("Opening the file for reading failed.");
    }
  } else if (error != nullptr) {
    error->append("The file does not exist.");
  }
  return success;
}

/**
 * @brief Tests if buildFile is older than sourceFile
 * @return True if buildFile  is older than sourceFile.
 *         False may indicate an error.
 */
static bool FileIsOlderThan(std::string const& buildFile,
                            std::string const& sourceFile,
                            std::string* error = nullptr)
{
  int result = 0;
  if (cmSystemTools::FileTimeCompare(buildFile, sourceFile, &result)) {
    return (result < 0);
  }
  if (error != nullptr) {
    error->append(
      "File modification time comparison failed for the files\n  ");
    error->append(cmQtAutoGen::Quoted(buildFile));
    error->append("\nand\n  ");
    error->append(cmQtAutoGen::Quoted(sourceFile));
  }
  return false;
}

static bool ListContains(std::vector<std::string> const& list,
                         std::string const& entry)
{
  return (std::find(list.begin(), list.end(), entry) != list.end());
}

// -- Class methods

cmQtAutoGenerators::cmQtAutoGenerators()
  : MultiConfig(cmQtAutoGen::WRAP)
  , IncludeProjectDirsBefore(false)
  , Verbose(cmSystemTools::HasEnv("VERBOSE"))
  , ColorOutput(true)
  , MocSettingsChanged(false)
  , MocPredefsChanged(false)
  , MocRelaxedMode(false)
  , UicSettingsChanged(false)
  , RccSettingsChanged(false)
{
  {
    std::string colorEnv;
    cmSystemTools::GetEnv("COLOR", colorEnv);
    if (!colorEnv.empty()) {
      this->ColorOutput = cmSystemTools::IsOn(colorEnv.c_str());
    }
  }

  // Precompile regular expressions
  this->MocRegExpInclude.compile(
    "[\n][ \t]*#[ \t]*include[ \t]+"
    "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
  this->UicRegExpInclude.compile("[\n][ \t]*#[ \t]*include[ \t]+"
                                 "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]");
}

bool cmQtAutoGenerators::Run(std::string const& targetDirectory,
                             std::string const& config)
{
  cmake cm(cmake::RoleScript);
  cm.SetHomeOutputDirectory(targetDirectory);
  cm.SetHomeDirectory(targetDirectory);
  cm.GetCurrentSnapshot().SetDefaultDefinitions();
  cmGlobalGenerator gg(&cm);

  cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
  snapshot.GetDirectory().SetCurrentBinary(targetDirectory);
  snapshot.GetDirectory().SetCurrentSource(targetDirectory);

  auto makefile = cm::make_unique<cmMakefile>(&gg, snapshot);
  gg.SetCurrentMakefile(makefile.get());

  bool success = false;
  if (this->InitInfoFile(makefile.get(), targetDirectory, config)) {
    // Read latest settings
    this->SettingsFileRead(makefile.get());
    if (this->Process()) {
      // Write current settings
      if (this->SettingsFileWrite()) {
        success = true;
      }
    }
  }
  return success;
}

bool cmQtAutoGenerators::InitInfoFile(cmMakefile* makefile,
                                      std::string const& targetDirectory,
                                      std::string const& config)
{
  // -- Meta
  this->HeaderExtensions = makefile->GetCMakeInstance()->GetHeaderExtensions();

  // Utility lambdas
  auto InfoGet = [makefile](const char* key) {
    return makefile->GetSafeDefinition(key);
  };
  auto InfoGetBool = [makefile](const char* key) {
    return makefile->IsOn(key);
  };
  auto InfoGetList = [makefile](const char* key) -> std::vector<std::string> {
    std::vector<std::string> list;
    cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list);
    return list;
  };
  auto InfoGetLists =
    [makefile](const char* key) -> std::vector<std::vector<std::string>> {
    std::vector<std::vector<std::string>> lists;
    {
      std::string const value = makefile->GetSafeDefinition(key);
      std::string::size_type pos = 0;
      while (pos < value.size()) {
        std::string::size_type next = value.find(cmQtAutoGen::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);
          {
            std::string subValue(itBeg, itEnd);
            std::vector<std::string> list;
            cmSystemTools::ExpandListArgument(subValue, list);
            lists.push_back(std::move(list));
          }
        }
        pos += length;
        pos += cmQtAutoGen::listSep.size();
      }
    }
    return lists;
  };
  auto InfoGetConfig = [makefile, &config](const char* key) -> std::string {
    const char* valueConf = nullptr;
    {
      std::string keyConf = key;
      keyConf += '_';
      keyConf += config;
      valueConf = makefile->GetDefinition(keyConf);
    }
    if (valueConf == nullptr) {
      valueConf = makefile->GetSafeDefinition(key);
    }
    return std::string(valueConf);
  };
  auto InfoGetConfigList =
    [&InfoGetConfig](const char* key) -> std::vector<std::string> {
    std::vector<std::string> list;
    cmSystemTools::ExpandListArgument(InfoGetConfig(key), list);
    return list;
  };

  // -- Read info file
  this->InfoFile = cmSystemTools::CollapseFullPath(targetDirectory);
  cmSystemTools::ConvertToUnixSlashes(this->InfoFile);
  this->InfoFile += "/AutogenInfo.cmake";
  if (!makefile->ReadListFile(this->InfoFile.c_str())) {
    this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
                       "File processing failed");
    return false;
  }

  // -- Meta
  this->MultiConfig = cmQtAutoGen::MultiConfigType(InfoGet("AM_MULTI_CONFIG"));
  this->ConfigSuffix = InfoGetConfig("AM_CONFIG_SUFFIX");
  if (this->ConfigSuffix.empty()) {
    this->ConfigSuffix = "_";
    this->ConfigSuffix += config;
  }

  // - Files and directories
  this->ProjectSourceDir = InfoGet("AM_CMAKE_SOURCE_DIR");
  this->ProjectBinaryDir = InfoGet("AM_CMAKE_BINARY_DIR");
  this->CurrentSourceDir = InfoGet("AM_CMAKE_CURRENT_SOURCE_DIR");
  this->CurrentBinaryDir = InfoGet("AM_CMAKE_CURRENT_BINARY_DIR");
  this->IncludeProjectDirsBefore =
    InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
  this->AutogenBuildDir = InfoGet("AM_BUILD_DIR");
  if (this->AutogenBuildDir.empty()) {
    this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
                       "Autogen build directory missing");
    return false;
  }

  // - Qt environment
  this->QtMajorVersion = InfoGet("AM_QT_VERSION_MAJOR");
  this->QtMinorVersion = InfoGet("AM_QT_VERSION_MINOR");
  this->MocExecutable = InfoGet("AM_QT_MOC_EXECUTABLE");
  this->UicExecutable = InfoGet("AM_QT_UIC_EXECUTABLE");
  this->RccExecutable = InfoGet("AM_QT_RCC_EXECUTABLE");

  // Check Qt version
  if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) {
    this->LogFileError(cmQtAutoGen::GEN, this->InfoFile,
                       "Unsupported Qt version: " +
                         cmQtAutoGen::Quoted(this->QtMajorVersion));
    return false;
  }

  // - Moc
  if (this->MocEnabled()) {
    this->MocSkipList = InfoGetList("AM_MOC_SKIP");
    this->MocDefinitions = InfoGetConfigList("AM_MOC_DEFINITIONS");
#ifdef _WIN32
    {
      std::string const win32("WIN32");
      if (!ListContains(this->MocDefinitions, win32)) {
        this->MocDefinitions.push_back(win32);
      }
    }
#endif
    this->MocIncludePaths = InfoGetConfigList("AM_MOC_INCLUDES");
    this->MocOptions = InfoGetList("AM_MOC_OPTIONS");
    this->MocRelaxedMode = InfoGetBool("AM_MOC_RELAXED_MODE");
    {
      std::vector<std::string> const MocMacroNames =
        InfoGetList("AM_MOC_MACRO_NAMES");
      for (std::string const& item : MocMacroNames) {
        this->MocMacroFilters.emplace_back(
          item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
      }
    }
    {
      std::vector<std::string> const mocDependFilters =
        InfoGetList("AM_MOC_DEPEND_FILTERS");
      // Insert Q_PLUGIN_METADATA dependency filter
      if (this->QtMajorVersion != "4") {
        this->MocDependFilterPush("Q_PLUGIN_METADATA",
                                  "[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
                                  "[^\\)]*FILE[ \t]*\"([^\"]+)\"");
      }
      // Insert user defined dependency filters
      if ((mocDependFilters.size() % 2) == 0) {
        for (std::vector<std::string>::const_iterator
               dit = mocDependFilters.begin(),
               ditEnd = mocDependFilters.end();
             dit != ditEnd; dit += 2) {
          if (!this->MocDependFilterPush(*dit, *(dit + 1))) {
            return false;
          }
        }
      } else {
        this->LogFileError(
          cmQtAutoGen::MOC, this->InfoFile,
          "AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2");
        return false;
      }
    }
    this->MocPredefsCmd = InfoGetList("AM_MOC_PREDEFS_CMD");
  }

  // - Uic
  if (this->UicEnabled()) {
    this->UicSkipList = InfoGetList("AM_UIC_SKIP");
    this->UicSearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS");
    this->UicTargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS");
    {
      auto sources = InfoGetList("AM_UIC_OPTIONS_FILES");
      auto options = InfoGetLists("AM_UIC_OPTIONS_OPTIONS");
      // Compare list sizes
      if (sources.size() != options.size()) {
        std::ostringstream ost;
        ost << "files/options lists sizes missmatch (" << sources.size() << "/"
            << options.size() << ")";
        this->LogFileError(cmQtAutoGen::UIC, this->InfoFile, ost.str());
        return false;
      }
      auto fitEnd = sources.cend();
      auto fit = sources.begin();
      auto oit = options.begin();
      while (fit != fitEnd) {
        this->UicOptions[*fit] = std::move(*oit);
        ++fit;
        ++oit;
      }
    }
  }

  // - Rcc
  if (this->RccEnabled()) {
    // File lists
    auto sources = InfoGetList("AM_RCC_SOURCES");
    auto builds = InfoGetList("AM_RCC_BUILDS");
    auto options = InfoGetLists("AM_RCC_OPTIONS");
    auto inputs = InfoGetLists("AM_RCC_INPUTS");

    if (sources.size() != builds.size()) {
      std::ostringstream ost;
      ost << "sources, builds lists sizes missmatch (" << sources.size() << "/"
          << builds.size() << ")";
      this->LogFileError(cmQtAutoGen::RCC, this->InfoFile, ost.str());
      return false;
    }
    if (sources.size() != options.size()) {
      std::ostringstream ost;
      ost << "sources, options lists sizes missmatch (" << sources.size()
          << "/" << options.size() << ")";
      this->LogFileError(cmQtAutoGen::RCC, this->InfoFile, ost.str());
      return false;
    }
    if (sources.size() != inputs.size()) {
      std::ostringstream ost;
      ost << "sources, inputs lists sizes missmatch (" << sources.size() << "/"
          << inputs.size() << ")";
      this->LogFileError(cmQtAutoGen::RCC, this->InfoFile, ost.str());
      return false;
    }
    {
      auto srcItEnd = sources.end();
      auto srcIt = sources.begin();
      auto bldIt = builds.begin();
      auto optIt = options.begin();
      auto inpIt = inputs.begin();
      while (srcIt != srcItEnd) {
        this->RccJobs.push_back(RccJob{ std::move(*srcIt), std::move(*bldIt),
                                        std::move(*optIt),
                                        std::move(*inpIt) });
        ++srcIt;
        ++bldIt;
        ++optIt;
        ++inpIt;
      }
    }
  }

  // Initialize source file jobs
  {
    // Utility lambdas
    auto AddJob = [this](std::map<std::string, SourceJob>& jobs,
                         std::string&& sourceFile) {
      const bool moc = !this->MocSkip(sourceFile);
      const bool uic = !this->UicSkip(sourceFile);
      if (moc || uic) {
        SourceJob& job = jobs[std::move(sourceFile)];
        job.Moc = moc;
        job.Uic = uic;
      }
    };

    // Add header jobs
    for (std::string& hdr : InfoGetList("AM_HEADERS")) {
      AddJob(this->HeaderJobs, std::move(hdr));
    }
    // Add source jobs
    {
      std::vector<std::string> sources = InfoGetList("AM_SOURCES");
      // Add header(s) for the source file
      for (std::string const& src : sources) {
        const bool srcMoc = !this->MocSkip(src);
        const bool srcUic = !this->UicSkip(src);
        if (!srcMoc && !srcUic) {
          continue;
        }
        // Search for the default header file and a private header
        std::array<std::string, 2> headerBases;
        headerBases[0] = SubDirPrefix(src);
        headerBases[0] += cmSystemTools::GetFilenameWithoutLastExtension(src);
        headerBases[1] = headerBases[0];
        headerBases[1] += "_p";
        for (std::string const& headerBase : headerBases) {
          std::string header;
          if (this->FindHeader(header, headerBase)) {
            const bool moc = srcMoc && !this->MocSkip(header);
            const bool uic = srcUic && !this->UicSkip(header);
            if (moc || uic) {
              SourceJob& job = this->HeaderJobs[std::move(header)];
              job.Moc = moc;
              job.Uic = uic;
            }
          }
        }
      }
      // Add Source jobs
      for (std::string& src : sources) {
        AddJob(this->SourceJobs, std::move(src));
      }
    }
  }

  // Init derived information
  // ------------------------

  // Init file path checksum generator
  this->FilePathChecksum.setupParentDirs(
    this->CurrentSourceDir, this->CurrentBinaryDir, this->ProjectSourceDir,
    this->ProjectBinaryDir);

  // include directory
  this->AutogenIncludeDir = "include";
  if (this->MultiConfig != cmQtAutoGen::SINGLE) {
    this->AutogenIncludeDir += this->ConfigSuffix;
  }
  this->AutogenIncludeDir += "/";

  // Moc variables
  if (this->MocEnabled()) {
    // Mocs compilation file
    this->MocCompFileRel = "mocs_compilation";
    if (this->MultiConfig == cmQtAutoGen::FULL) {
      this->MocCompFileRel += this->ConfigSuffix;
    }
    this->MocCompFileRel += ".cpp";
    this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath(
      this->AutogenBuildDir, this->MocCompFileRel);

    // Moc predefs file
    if (!this->MocPredefsCmd.empty()) {
      this->MocPredefsFileRel = "moc_predefs";
      if (this->MultiConfig != cmQtAutoGen::SINGLE) {
        this->MocPredefsFileRel += this->ConfigSuffix;
      }
      this->MocPredefsFileRel += ".h";
      this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath(
        this->AutogenBuildDir, this->MocPredefsFileRel);
    }

    // Sort include directories on demand
    if (this->IncludeProjectDirsBefore) {
      // Move strings to temporary list
      std::list<std::string> includes;
      includes.insert(includes.end(), this->MocIncludePaths.begin(),
                      this->MocIncludePaths.end());
      this->MocIncludePaths.clear();
      this->MocIncludePaths.reserve(includes.size());
      // Append project directories only
      {
        std::array<std::string const*, 2> const movePaths = {
          { &this->ProjectBinaryDir, &this->ProjectSourceDir }
        };
        for (std::string const* ppath : movePaths) {
          std::list<std::string>::iterator it = includes.begin();
          while (it != includes.end()) {
            std::string const& path = *it;
            if (cmSystemTools::StringStartsWith(path, ppath->c_str())) {
              this->MocIncludePaths.push_back(path);
              it = includes.erase(it);
            } else {
              ++it;
            }
          }
        }
      }
      // Append remaining directories
      this->MocIncludePaths.insert(this->MocIncludePaths.end(),
                                   includes.begin(), includes.end());
    }
    // Compose moc includes list
    {
      std::set<std::string> frameworkPaths;
      for (std::string const& path : this->MocIncludePaths) {
        this->MocIncludes.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);
          std::string frameworkPath = cmSystemTools::JoinPath(
            pathComponents.begin(), pathComponents.end() - 2);
          frameworkPaths.insert(frameworkPath);
        }
      }
      // Append framework includes
      for (std::string const& path : frameworkPaths) {
        this->MocIncludes.push_back("-F");
        this->MocIncludes.push_back(path);
      }
    }
    // Setup single list with all options
    {
      // Add includes
      this->MocAllOptions.insert(this->MocAllOptions.end(),
                                 this->MocIncludes.begin(),
                                 this->MocIncludes.end());
      // Add definitions
      for (std::string const& def : this->MocDefinitions) {
        this->MocAllOptions.push_back("-D" + def);
      }
      // Add options
      this->MocAllOptions.insert(this->MocAllOptions.end(),
                                 this->MocOptions.begin(),
                                 this->MocOptions.end());
    }
  }

  // - Old settings file
  {
    this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory);
    cmSystemTools::ConvertToUnixSlashes(this->SettingsFile);
    this->SettingsFile += "/AutogenOldSettings";
    if (this->MultiConfig != cmQtAutoGen::SINGLE) {
      this->SettingsFile += this->ConfigSuffix;
    }
    this->SettingsFile += ".cmake";
  }

  return true;
}

void cmQtAutoGenerators::SettingsFileRead(cmMakefile* makefile)
{
  // Compose current settings strings
  {
    cmCryptoHash crypt(cmCryptoHash::AlgoSHA256);
    std::string const sep(" ~~~ ");
    if (this->MocEnabled()) {
      std::string str;
      str += this->MocExecutable;
      str += sep;
      str += cmJoin(this->MocAllOptions, ";");
      str += sep;
      str += this->IncludeProjectDirsBefore ? "TRUE" : "FALSE";
      str += sep;
      str += cmJoin(this->MocPredefsCmd, ";");
      str += sep;
      this->SettingsStringMoc = crypt.HashString(str);
    }
    if (this->UicEnabled()) {
      std::string str;
      str += this->UicExecutable;
      str += sep;
      str += cmJoin(this->UicTargetOptions, ";");
      for (const auto& item : this->UicOptions) {
        str += sep;
        str += item.first;
        str += sep;
        str += cmJoin(item.second, ";");
      }
      str += sep;
      this->SettingsStringUic = crypt.HashString(str);
    }
    if (this->RccEnabled()) {
      std::string str;
      str += this->RccExecutable;
      for (const RccJob& rccJob : this->RccJobs) {
        str += sep;
        str += rccJob.QrcFile;
        str += sep;
        str += rccJob.RccFile;
        str += sep;
        str += cmJoin(rccJob.Options, ";");
      }
      str += sep;
      this->SettingsStringRcc = crypt.HashString(str);
    }
  }

  // Read old settings
  if (makefile->ReadListFile(this->SettingsFile.c_str())) {
    {
      auto SMatch = [makefile](const char* key, std::string const& value) {
        return (value == makefile->GetSafeDefinition(key));
      };
      if (!SMatch(SettingsKeyMoc, this->SettingsStringMoc)) {
        this->MocSettingsChanged = true;
      }
      if (!SMatch(SettingsKeyUic, this->SettingsStringUic)) {
        this->UicSettingsChanged = true;
      }
      if (!SMatch(SettingsKeyRcc, this->SettingsStringRcc)) {
        this->RccSettingsChanged = 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 (this->SettingsChanged()) {
      cmSystemTools::RemoveFile(this->SettingsFile);
    }
  } else {
    // If the file could not be read re-generate everythiung.
    this->MocSettingsChanged = true;
    this->UicSettingsChanged = true;
    this->RccSettingsChanged = true;
  }
}

bool cmQtAutoGenerators::SettingsFileWrite()
{
  bool success = true;
  // Only write if any setting changed
  if (this->SettingsChanged()) {
    if (this->Verbose) {
      this->LogInfo(cmQtAutoGen::GEN, "Writing settings file " +
                      cmQtAutoGen::Quoted(this->SettingsFile));
    }
    // Compose settings file content
    std::string settings;
    {
      auto SettingAppend = [&settings](const char* key,
                                       std::string const& value) {
        settings += "set(";
        settings += key;
        settings += " ";
        settings += cmOutputConverter::EscapeForCMake(value);
        settings += ")\n";
      };
      SettingAppend(SettingsKeyMoc, this->SettingsStringMoc);
      SettingAppend(SettingsKeyUic, this->SettingsStringUic);
      SettingAppend(SettingsKeyRcc, this->SettingsStringRcc);
    }
    // Write settings file
    if (!this->FileWrite(cmQtAutoGen::GEN, this->SettingsFile, settings)) {
      this->LogFileError(cmQtAutoGen::GEN, this->SettingsFile,
                         "Settings file writing failed");
      // Remove old settings file to trigger a full rebuild on the next run
      cmSystemTools::RemoveFile(this->SettingsFile);
      success = false;
    }
  }
  return success;
}

bool cmQtAutoGenerators::Process()
{
  // the program goes through all .cpp files to see which moc files are
  // included. It is not really interesting how the moc file is named, but
  // what file the moc is created from. Once a moc is included the same moc
  // may not be included in the mocs_compilation.cpp file anymore.
  // OTOH if there's a header containing Q_OBJECT where no corresponding
  // moc file is included anywhere a moc_<filename>.cpp file is created and
  // included in the mocs_compilation.cpp file.

  // Create AUTOGEN include directory
  {
    std::string const incDirAbs = cmSystemTools::CollapseCombinedPath(
      this->AutogenBuildDir, this->AutogenIncludeDir);
    if (!cmSystemTools::MakeDirectory(incDirAbs)) {
      this->LogFileError(cmQtAutoGen::GEN, incDirAbs,
                         "Could not create directory");
      return false;
    }
  }

  // Parse source files
  for (const auto& item : this->SourceJobs) {
    if (!this->ParseSourceFile(item.first, item.second)) {
      return false;
    }
  }
  // Parse header files
  for (const auto& item : this->HeaderJobs) {
    if (!this->ParseHeaderFile(item.first, item.second)) {
      return false;
    }
  }
  // Read missing dependency information
  if (!this->ParsePostprocess()) {
    return false;
  }

  // Generate files
  if (!this->MocGenerateAll()) {
    return false;
  }
  if (!this->UicGenerateAll()) {
    return false;
  }
  if (!this->RccGenerateAll()) {
    return false;
  }

  return true;
}

/**
 * @return True on success
 */
bool cmQtAutoGenerators::ParseSourceFile(std::string const& absFilename,
                                         const SourceJob& job)
{
  std::string contentText;
  std::string error;
  bool success = ReadFile(contentText, absFilename, &error);
  if (success) {
    if (!contentText.empty()) {
      if (job.Moc) {
        success = this->MocParseSourceContent(absFilename, contentText);
      }
      if (success && job.Uic) {
        success = this->UicParseContent(absFilename, contentText);
      }
    } else {
      this->LogFileWarning(cmQtAutoGen::GEN, absFilename,
                           "The source file is empty");
    }
  } else {
    this->LogFileError(cmQtAutoGen::GEN, absFilename,
                       "Could not read the source file: " + error);
  }
  return success;
}

/**
 * @return True on success
 */
bool cmQtAutoGenerators::ParseHeaderFile(std::string const& absFilename,
                                         const SourceJob& job)
{
  std::string contentText;
  std::string error;
  bool success = ReadFile(contentText, absFilename, &error);
  if (success) {
    if (!contentText.empty()) {
      if (job.Moc) {
        this->MocParseHeaderContent(absFilename, contentText);
      }
      if (job.Uic) {
        success = this->UicParseContent(absFilename, contentText);
      }
    } else {
      this->LogFileWarning(cmQtAutoGen::GEN, absFilename,
                           "The header file is empty");
    }
  } else {
    this->LogFileError(cmQtAutoGen::GEN, absFilename,
                       "Could not read the header file: " + error);
  }
  return success;
}

/**
 * @return True on success
 */
bool cmQtAutoGenerators::ParsePostprocess()
{
  bool success = true;
  // Read missin dependecies
  for (auto& item : this->MocJobsIncluded) {
    if (!item->DependsValid) {
      std::string content;
      std::string error;
      if (ReadFile(content, item->SourceFile, &error)) {
        this->MocFindDepends(item->SourceFile, content, item->Depends);
        item->DependsValid = true;
      } else {
        std::string emsg = "Could not read file\n  ";
        emsg += item->SourceFile;
        emsg += "\nrequired by moc include \"";
        emsg += item->IncludeString;
        emsg += "\".\n";
        emsg += error;
        this->LogFileError(cmQtAutoGen::MOC, item->Includer, emsg);
        success = false;
        break;
      }
    }
  }
  return success;
}

/**
 * @brief Tests if the file should be ignored for moc scanning
 * @return True if the file should be ignored
 */
bool cmQtAutoGenerators::MocSkip(std::string const& absFilename) const
{
  if (this->MocEnabled()) {
    // Test if the file name is on the skip list
    if (!ListContains(this->MocSkipList, absFilename)) {
      return false;
    }
  }
  return true;
}

/**
 * @brief Tests if the C++ content requires moc processing
 * @return True if moc is required
 */
bool cmQtAutoGenerators::MocRequired(std::string const& contentText,
                                     std::string* macroName)
{
  for (KeyRegExp& filter : this->MocMacroFilters) {
    // Run a simple find string operation before the expensive
    // regular expression check
    if (contentText.find(filter.Key) != std::string::npos) {
      if (filter.RegExp.find(contentText)) {
        // Return macro name on demand
        if (macroName != nullptr) {
          *macroName = filter.Key;
        }
        return true;
      }
    }
  }
  return false;
}

std::string cmQtAutoGenerators::MocStringMacros() const
{
  std::string res;
  const auto itB = this->MocMacroFilters.cbegin();
  const auto itE = this->MocMacroFilters.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;
}

std::string cmQtAutoGenerators::MocStringHeaders(
  std::string const& fileBase) const
{
  std::string res = fileBase;
  res += ".{";
  res += cmJoin(this->HeaderExtensions, ",");
  res += "}";
  return res;
}

std::string cmQtAutoGenerators::MocFindIncludedHeader(
  std::string const& sourcePath, std::string const& includeBase) const
{
  std::string header;
  // Search in vicinity of the source
  if (!this->FindHeader(header, sourcePath + includeBase)) {
    // Search in include directories
    for (std::string const& path : this->MocIncludePaths) {
      std::string fullPath = path;
      fullPath.push_back('/');
      fullPath += includeBase;
      if (this->FindHeader(header, fullPath)) {
        break;
      }
    }
  }
  // Sanitize
  if (!header.empty()) {
    header = cmSystemTools::GetRealPath(header);
  }
  return header;
}

bool cmQtAutoGenerators::MocFindIncludedFile(
  std::string& absFile, std::string const& sourcePath,
  std::string const& includeString) const
{
  bool success = false;
  // Search in vicinity of the source
  {
    std::string testPath = sourcePath;
    testPath += includeString;
    if (cmSystemTools::FileExists(testPath.c_str())) {
      absFile = cmSystemTools::GetRealPath(testPath);
      success = true;
    }
  }
  // Search in include directories
  if (!success) {
    for (std::string const& path : this->MocIncludePaths) {
      std::string fullPath = path;
      fullPath.push_back('/');
      fullPath += includeString;
      if (cmSystemTools::FileExists(fullPath.c_str())) {
        absFile = cmSystemTools::GetRealPath(fullPath);
        success = true;
        break;
      }
    }
  }
  return success;
}

bool cmQtAutoGenerators::MocDependFilterPush(std::string const& key,
                                             std::string const& regExp)
{
  std::string error;
  if (!key.empty()) {
    if (!regExp.empty()) {
      KeyRegExp filter;
      filter.Key = key;
      if (filter.RegExp.compile(regExp)) {
        this->MocDependFilters.push_back(std::move(filter));
      } else {
        error = "Regular expression compiling failed";
      }
    } else {
      error = "Regular expression is empty";
    }
  } else {
    error = "Key is empty";
  }
  if (!error.empty()) {
    std::string emsg = "AUTOMOC_DEPEND_FILTERS: ";
    emsg += error;
    emsg += "\n";
    emsg += "  Key:    ";
    emsg += cmQtAutoGen::Quoted(key);
    emsg += "\n";
    emsg += "  RegExp: ";
    emsg += cmQtAutoGen::Quoted(regExp);
    emsg += "\n";
    this->LogError(cmQtAutoGen::MOC, emsg);
    return false;
  }
  return true;
}

void cmQtAutoGenerators::MocFindDepends(std::string const& absFilename,
                                        std::string const& contentText,
                                        std::set<std::string>& depends)
{
  if (this->MocDependFilters.empty() && contentText.empty()) {
    return;
  }

  std::vector<std::string> matches;
  for (KeyRegExp& filter : this->MocDependFilters) {
    // Run a simple find string check
    if (contentText.find(filter.Key) != std::string::npos) {
      // Run the expensive regular expression check loop
      const char* contentChars = contentText.c_str();
      while (filter.RegExp.find(contentChars)) {
        std::string match = filter.RegExp.match(1);
        if (!match.empty()) {
          matches.emplace_back(std::move(match));
        }
        contentChars += filter.RegExp.end();
      }
    }
  }

  if (!matches.empty()) {
    std::string const sourcePath = SubDirPrefix(absFilename);
    for (std::string const& match : matches) {
      // Find the dependency file
      std::string incFile;
      if (this->MocFindIncludedFile(incFile, sourcePath, match)) {
        depends.insert(incFile);
        if (this->Verbose) {
          this->LogInfo(cmQtAutoGen::MOC, "Found dependency:\n  " +
                          cmQtAutoGen::Quoted(absFilename) + "\n  " +
                          cmQtAutoGen::Quoted(incFile));
        }
      } else {
        this->LogFileWarning(cmQtAutoGen::MOC, absFilename,
                             "Could not find dependency file " +
                               cmQtAutoGen::Quoted(match));
      }
    }
  }
}

/**
 * @return True on success
 */
bool cmQtAutoGenerators::MocParseSourceContent(std::string const& absFilename,
                                               std::string const& contentText)
{
  if (this->Verbose) {
    this->LogInfo(cmQtAutoGen::MOC, "Checking: " + absFilename);
  }

  auto AddJob = [this, &absFilename](std::string const& sourceFile,
                                     std::string const& includeString,
                                     std::string const* content) {
    auto job = cm::make_unique<MocJobIncluded>();
    job->SourceFile = sourceFile;
    job->BuildFileRel = this->AutogenIncludeDir;
    job->BuildFileRel += includeString;
    job->Includer = absFilename;
    job->IncludeString = includeString;
    job->DependsValid = (content != nullptr);
    if (job->DependsValid) {
      this->MocFindDepends(sourceFile, *content, job->Depends);
    }
    this->MocJobsIncluded.push_back(std::move(job));
  };

  struct MocInc
  {
    std::string Inc;  // full include string
    std::string Dir;  // include string directory
    std::string Base; // include string file base
  };

  // Extract moc includes from file
  std::vector<MocInc> mocIncsUsc;
  std::vector<MocInc> mocIncsDot;
  {
    const char* contentChars = contentText.c_str();
    if (strstr(contentChars, "moc") != nullptr) {
      while (this->MocRegExpInclude.find(contentChars)) {
        std::string incString = this->MocRegExpInclude.match(1);
        std::string incDir(SubDirPrefix(incString));
        std::string incBase =
          cmSystemTools::GetFilenameWithoutLastExtension(incString);
        if (cmHasLiteralPrefix(incBase, "moc_")) {
          // moc_<BASE>.cxx
          // Remove the moc_ part from the base name
          mocIncsUsc.push_back(MocInc{ std::move(incString), std::move(incDir),
                                       incBase.substr(4) });
        } else {
          // <BASE>.moc
          mocIncsDot.push_back(MocInc{ std::move(incString), std::move(incDir),
                                       std::move(incBase) });
        }
        // Forward content pointer
        contentChars += this->MocRegExpInclude.end();
      }
    }
  }

  std::string selfMacroName;
  const bool selfRequiresMoc = this->MocRequired(contentText, &selfMacroName);

  // Check if there is anything to do
  if (!selfRequiresMoc && mocIncsUsc.empty() && mocIncsDot.empty()) {
    return true;
  }

  // Scan file variables
  std::string const scanFileDir = SubDirPrefix(absFilename);
  std::string const scanFileBase =
    cmSystemTools::GetFilenameWithoutLastExtension(absFilename);
  // Relaxed mode variables
  bool ownDotMocIncluded = false;
  std::string ownMocUscInclude;
  std::string ownMocUscHeader;

  // Process moc_<BASE>.cxx includes
  for (const MocInc& mocInc : mocIncsUsc) {
    std::string const header =
      this->MocFindIncludedHeader(scanFileDir, mocInc.Dir + mocInc.Base);
    if (!header.empty()) {
      // Check if header is skipped
      if (this->MocSkip(header)) {
        continue;
      }
      // Register moc job
      AddJob(header, mocInc.Inc, nullptr);
      // Store meta information for relaxed mode
      if (this->MocRelaxedMode && (mocInc.Base == scanFileBase)) {
        ownMocUscInclude = mocInc.Inc;
        ownMocUscHeader = header;
      }
    } else {
      std::string emsg = "The file includes the moc file ";
      emsg += cmQtAutoGen::Quoted(mocInc.Inc);
      emsg += ", but could not find the header ";
      emsg += cmQtAutoGen::Quoted(this->MocStringHeaders(mocInc.Base));
      this->LogFileError(cmQtAutoGen::MOC, absFilename, emsg);
      return false;
    }
  }

  // Process <BASE>.moc includes
  for (const MocInc& mocInc : mocIncsDot) {
    const bool ownMoc = (mocInc.Base == scanFileBase);
    if (this->MocRelaxedMode) {
      // Relaxed mode
      if (selfRequiresMoc && ownMoc) {
        // Add self
        AddJob(absFilename, mocInc.Inc, &contentText);
        ownDotMocIncluded = true;
      } else {
        // In relaxed mode try to find a header instead but issue a warning.
        // This is for KDE4 compatibility
        std::string const header =
          this->MocFindIncludedHeader(scanFileDir, mocInc.Dir + mocInc.Base);
        if (!header.empty()) {
          // Check if header is skipped
          if (this->MocSkip(header)) {
            continue;
          }
          // Register moc job
          AddJob(header, mocInc.Inc, nullptr);
          if (!selfRequiresMoc) {
            if (ownMoc) {
              std::string emsg = "The file includes the moc file ";
              emsg += cmQtAutoGen::Quoted(mocInc.Inc);
              emsg += ", but does not contain a ";
              emsg += this->MocStringMacros();
              emsg += " macro.\nRunning moc on\n  ";
              emsg += cmQtAutoGen::Quoted(header);
              emsg += "!\nBetter include ";
              emsg += cmQtAutoGen::Quoted("moc_" + mocInc.Base + ".cpp");
              emsg += " for a compatibility with strict mode.\n"
                      "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n";
              this->LogFileWarning(cmQtAutoGen::MOC, absFilename, emsg);
            } else {
              std::string emsg = "The file includes the moc file ";
              emsg += cmQtAutoGen::Quoted(mocInc.Inc);
              emsg += " instead of ";
              emsg += cmQtAutoGen::Quoted("moc_" + mocInc.Base + ".cpp");
              emsg += ".\nRunning moc on\n  ";
              emsg += cmQtAutoGen::Quoted(header);
              emsg += "!\nBetter include ";
              emsg += cmQtAutoGen::Quoted("moc_" + mocInc.Base + ".cpp");
              emsg += " for compatibility with strict mode.\n"
                      "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n";
              this->LogFileWarning(cmQtAutoGen::MOC, absFilename, emsg);
            }
          }
        } else {
          std::string emsg = "The file includes the moc file ";
          emsg += cmQtAutoGen::Quoted(mocInc.Inc);
          emsg += ", which seems to be the moc file from a different "
                  "source file. CMake also could not find a matching "
                  "header.";
          this->LogFileError(cmQtAutoGen::MOC, absFilename, emsg);
          return false;
        }
      }
    } else {
      // Strict mode
      if (ownMoc) {
        // Include self
        AddJob(absFilename, mocInc.Inc, &contentText);
        ownDotMocIncluded = true;
        // Accept but issue a warning if moc isn't required
        if (!selfRequiresMoc) {
          std::string emsg = "The file includes the moc file ";
          emsg += cmQtAutoGen::Quoted(mocInc.Inc);
          emsg += ", but does not contain a ";
          emsg += this->MocStringMacros();
          emsg += " macro.";
          this->LogFileWarning(cmQtAutoGen::MOC, absFilename, emsg);
        }
      } else {
        // Don't allow <BASE>.moc include other than self in strict mode
        std::string emsg = "The file includes the moc file ";
        emsg += cmQtAutoGen::Quoted(mocInc.Inc);
        emsg += ", which seems to be the moc file from a different "
                "source file.\nThis is not supported. Include ";
        emsg += cmQtAutoGen::Quoted(scanFileBase + ".moc");
        emsg += " to run moc on this source file.";
        this->LogFileError(cmQtAutoGen::MOC, absFilename, emsg);
        return false;
      }
    }
  }

  if (selfRequiresMoc && !ownDotMocIncluded) {
    // In this case, check whether the scanned file itself contains a Q_OBJECT.
    // If this is the case, the moc_foo.cpp should probably be generated from
    // foo.cpp instead of foo.h, because otherwise it won't build.
    // But warn, since this is not how it is supposed to be used.
    if (this->MocRelaxedMode && !ownMocUscInclude.empty()) {
      // This is for KDE4 compatibility:
      std::string emsg = "The file contains a ";
      emsg += selfMacroName;
      emsg += " macro, but does not include ";
      emsg += cmQtAutoGen::Quoted(scanFileBase + ".moc");
      emsg += ". Instead it includes ";
      emsg += cmQtAutoGen::Quoted(ownMocUscInclude);
      emsg += ".\nRunning moc on\n  ";
      emsg += cmQtAutoGen::Quoted(absFilename);
      emsg += "!\nBetter include ";
      emsg += cmQtAutoGen::Quoted(scanFileBase + ".moc");
      emsg += " for compatibility with strict mode.\n"
              "(CMAKE_AUTOMOC_RELAXED_MODE warning)";
      this->LogFileWarning(cmQtAutoGen::MOC, absFilename, emsg);

      // Remove own header job
      {
        auto itC = this->MocJobsIncluded.begin();
        auto itE = this->MocJobsIncluded.end();
        for (; itC != itE; ++itC) {
          if ((*itC)->SourceFile == ownMocUscHeader) {
            if ((*itC)->IncludeString == ownMocUscInclude) {
              this->MocJobsIncluded.erase(itC);
              break;
            }
          }
        }
      }
      // Add own source job
      AddJob(absFilename, ownMocUscInclude, &contentText);
    } else {
      // Otherwise always error out since it will not compile:
      std::string emsg = "The file contains a ";
      emsg += selfMacroName;
      emsg += " macro, but does not include ";
      emsg += cmQtAutoGen::Quoted(scanFileBase + ".moc");
      emsg += "!\nConsider to\n - add #include \"";
      emsg += scanFileBase;
      emsg += ".moc\"\n - enable SKIP_AUTOMOC for this file";
      this->LogFileError(cmQtAutoGen::MOC, absFilename, emsg);
      return false;
    }
  }
  return true;
}

void cmQtAutoGenerators::MocParseHeaderContent(std::string const& absFilename,
                                               std::string const& contentText)
{
  if (this->Verbose) {
    this->LogInfo(cmQtAutoGen::MOC, "Checking: " + absFilename);
  }

  auto const fit =
    std::find_if(this->MocJobsIncluded.cbegin(), this->MocJobsIncluded.cend(),
                 [&absFilename](std::unique_ptr<MocJobIncluded> const& job) {
                   return job->SourceFile == absFilename;
                 });
  if (fit == this->MocJobsIncluded.cend()) {
    if (this->MocRequired(contentText)) {
      auto job = cm::make_unique<MocJobAuto>();
      job->SourceFile = absFilename;
      {
        std::string& bld = job->BuildFileRel;
        bld = this->FilePathChecksum.getPart(absFilename);
        bld += '/';
        bld += "moc_";
        bld += cmSystemTools::GetFilenameWithoutLastExtension(absFilename);
        if (this->MultiConfig != cmQtAutoGen::SINGLE) {
          bld += this->ConfigSuffix;
        }
        bld += ".cpp";
      }
      this->MocFindDepends(absFilename, contentText, job->Depends);
      this->MocJobsAuto.push_back(std::move(job));
    }
  }
}

bool cmQtAutoGenerators::MocGenerateAll()
{
  if (!this->MocEnabled()) {
    return true;
  }

  // Look for name collisions in included moc files
  {
    bool collision = false;
    std::map<std::string, std::vector<MocJobIncluded const*>> collisions;
    for (auto const& job : this->MocJobsIncluded) {
      auto& list = collisions[job->IncludeString];
      if (!list.empty()) {
        collision = true;
      }
      list.push_back(job.get());
    }
    if (collision) {
      std::string emsg =
        "Included moc files with the same name will be "
        "generated from different sources.\n"
        "Consider 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"
        "Include conflicts\n"
        "-----------------\n";
      const auto& colls = collisions;
      for (auto const& coll : colls) {
        if (coll.second.size() > 1) {
          emsg += cmQtAutoGen::Quoted(coll.first);
          emsg += " included in\n";
          for (const MocJobIncluded* job : coll.second) {
            emsg += " - ";
            emsg += cmQtAutoGen::Quoted(job->Includer);
            emsg += "\n";
          }
          emsg += "would be generated from\n";
          for (const MocJobIncluded* job : coll.second) {
            emsg += " - ";
            emsg += cmQtAutoGen::Quoted(job->SourceFile);
            emsg += "\n";
          }
        }
      }
      this->LogError(cmQtAutoGen::MOC, emsg);
      return false;
    }
  }

  // (Re)generate moc_predefs.h on demand
  if (!this->MocPredefsCmd.empty()) {
    if (this->MocSettingsChanged ||
        !cmSystemTools::FileExists(this->MocPredefsFileAbs)) {
      if (this->Verbose) {
        this->LogBold("Generating MOC predefs " + this->MocPredefsFileRel);
      }

      std::string output;
      {
        // Compose command
        std::vector<std::string> cmd = this->MocPredefsCmd;
        // Add options
        cmd.insert(cmd.end(), this->MocAllOptions.begin(),
                   this->MocAllOptions.end());
        // Execute command
        if (!this->RunCommand(cmd, output)) {
          this->LogCommandError(cmQtAutoGen::MOC,
                                "moc_predefs generation failed", cmd, output);
          return false;
        }
      }

      // (Re)write predefs file only on demand
      if (this->FileDiffers(this->MocPredefsFileAbs, output)) {
        if (this->FileWrite(cmQtAutoGen::MOC, this->MocPredefsFileAbs,
                            output)) {
          this->MocPredefsChanged = true;
        } else {
          this->LogFileError(cmQtAutoGen::MOC, this->MocPredefsFileAbs,
                             "moc_predefs file writing failed");
          return false;
        }
      } else {
        // Touch to update the time stamp
        if (this->Verbose) {
          this->LogInfo(cmQtAutoGen::MOC,
                        "Touching moc_predefs " + this->MocPredefsFileRel);
        }
        cmSystemTools::Touch(this->MocPredefsFileAbs, false);
      }
    }

    // Add moc_predefs.h to moc file dependecies
    for (auto const& item : this->MocJobsIncluded) {
      item->Depends.insert(this->MocPredefsFileAbs);
    }
    for (auto const& item : this->MocJobsAuto) {
      item->Depends.insert(this->MocPredefsFileAbs);
    }
  }

  // Generate moc files that are included by source files.
  for (auto const& item : this->MocJobsIncluded) {
    if (!this->MocGenerateFile(*item)) {
      return false;
    }
  }
  // Generate moc files that are _not_ included by source files.
  bool autoNameGenerated = false;
  for (auto const& item : this->MocJobsAuto) {
    if (!this->MocGenerateFile(*item, &autoNameGenerated)) {
      return false;
    }
  }

  // Compose mocs compilation file content
  {
    std::string mocs =
      "// This file is autogenerated. Changes will be overwritten.\n";
    if (this->MocJobsAuto.empty()) {
      // Placeholder content
      mocs +=
        "// No files found that require moc or the moc files are included\n";
      mocs += "enum some_compilers { need_more_than_nothing };\n";
    } else {
      // Valid content
      for (const auto& item : this->MocJobsAuto) {
        mocs += "#include \"";
        mocs += item->BuildFileRel;
        mocs += "\"\n";
      }
    }

    if (this->FileDiffers(this->MocCompFileAbs, mocs)) {
      // Actually write mocs compilation file
      if (this->Verbose) {
        this->LogBold("Generating MOC compilation " + this->MocCompFileRel);
      }
      if (!this->FileWrite(cmQtAutoGen::MOC, this->MocCompFileAbs, mocs)) {
        this->LogFileError(cmQtAutoGen::MOC, this->MocCompFileAbs,
                           "mocs compilation file writing failed");
        return false;
      }
    } else if (autoNameGenerated) {
      // Only touch mocs compilation file
      if (this->Verbose) {
        this->LogInfo(cmQtAutoGen::MOC,
                      "Touching mocs compilation " + this->MocCompFileRel);
      }
      cmSystemTools::Touch(this->MocCompFileAbs, false);
    }
  }

  return true;
}

/**
 * @return True on success
 */
bool cmQtAutoGenerators::MocGenerateFile(const MocJobAuto& mocJob,
                                         bool* generated)
{
  bool success = true;

  std::string const mocFileAbs = cmSystemTools::CollapseCombinedPath(
    this->AutogenBuildDir, mocJob.BuildFileRel);

  bool generate = false;
  std::string generateReason;
  if (!generate && !cmSystemTools::FileExists(mocFileAbs.c_str())) {
    if (this->Verbose) {
      generateReason = "Generating ";
      generateReason += cmQtAutoGen::Quoted(mocFileAbs);
      generateReason += " from its source file ";
      generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
      generateReason += " because it doesn't exist";
    }
    generate = true;
  }
  if (!generate && this->MocSettingsChanged) {
    if (this->Verbose) {
      generateReason = "Generating ";
      generateReason += cmQtAutoGen::Quoted(mocFileAbs);
      generateReason += " from ";
      generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
      generateReason += " because the MOC settings changed";
    }
    generate = true;
  }
  if (!generate && this->MocPredefsChanged) {
    if (this->Verbose) {
      generateReason = "Generating ";
      generateReason += cmQtAutoGen::Quoted(mocFileAbs);
      generateReason += " from ";
      generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
      generateReason += " because moc_predefs.h changed";
    }
    generate = true;
  }
  if (!generate) {
    std::string error;
    if (FileIsOlderThan(mocFileAbs, mocJob.SourceFile, &error)) {
      if (this->Verbose) {
        generateReason = "Generating ";
        generateReason += cmQtAutoGen::Quoted(mocFileAbs);
        generateReason += " because it's older than its source file ";
        generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
      }
      generate = true;
    } else {
      if (!error.empty()) {
        this->LogError(cmQtAutoGen::MOC, error);
        success = false;
      }
    }
  }
  if (success && !generate) {
    // Test if a dependency file is newer
    std::string error;
    for (std::string const& depFile : mocJob.Depends) {
      if (FileIsOlderThan(mocFileAbs, depFile, &error)) {
        if (this->Verbose) {
          generateReason = "Generating ";
          generateReason += cmQtAutoGen::Quoted(mocFileAbs);
          generateReason += " from ";
          generateReason += cmQtAutoGen::Quoted(mocJob.SourceFile);
          generateReason += " because it is older than ";
          generateReason += cmQtAutoGen::Quoted(depFile);
        }
        generate = true;
        break;
      }
      if (!error.empty()) {
        this->LogError(cmQtAutoGen::MOC, error);
        success = false;
        break;
      }
    }
  }

  if (generate) {
    // Log
    if (this->Verbose) {
      this->LogBold("Generating MOC source " + mocJob.BuildFileRel);
      this->LogInfo(cmQtAutoGen::MOC, generateReason);
    }

    // Make sure the parent directory exists
    if (this->MakeParentDirectory(cmQtAutoGen::MOC, mocFileAbs)) {
      // Compose moc command
      std::vector<std::string> cmd;
      cmd.push_back(this->MocExecutable);
      // Add options
      cmd.insert(cmd.end(), this->MocAllOptions.begin(),
                 this->MocAllOptions.end());
      // Add predefs include
      if (!this->MocPredefsFileAbs.empty()) {
        cmd.push_back("--include");
        cmd.push_back(this->MocPredefsFileAbs);
      }
      cmd.push_back("-o");
      cmd.push_back(mocFileAbs);
      cmd.push_back(mocJob.SourceFile);

      // Execute moc command
      std::string output;
      if (this->RunCommand(cmd, output)) {
        // Success
        if (generated != nullptr) {
          *generated = true;
        }
      } else {
        // Moc command failed
        {
          std::string emsg = "moc failed for\n  ";
          emsg += cmQtAutoGen::Quoted(mocJob.SourceFile);
          this->LogCommandError(cmQtAutoGen::MOC, emsg, cmd, output);
        }
        cmSystemTools::RemoveFile(mocFileAbs);
        success = false;
      }
    } else {
      // Parent directory creation failed
      success = false;
    }
  }
  return success;
}

/**
 * @brief Tests if the file name is in the skip list
 */
bool cmQtAutoGenerators::UicSkip(std::string const& absFilename) const
{
  if (this->UicEnabled()) {
    // Test if the file name is on the skip list
    if (!ListContains(this->UicSkipList, absFilename)) {
      return false;
    }
  }
  return true;
}

bool cmQtAutoGenerators::UicParseContent(std::string const& absFilename,
                                         std::string const& contentText)
{
  if (this->Verbose) {
    this->LogInfo(cmQtAutoGen::UIC, "Checking: " + absFilename);
  }

  std::vector<std::string> includes;
  // Extracte includes
  {
    const char* contentChars = contentText.c_str();
    if (strstr(contentChars, "ui_") != nullptr) {
      while (this->UicRegExpInclude.find(contentChars)) {
        includes.push_back(this->UicRegExpInclude.match(1));
        contentChars += this->UicRegExpInclude.end();
      }
    }
  }

  for (std::string const& includeString : includes) {
    std::string uiInputFile;
    if (!UicFindIncludedFile(uiInputFile, absFilename, includeString)) {
      return false;
    }
    // Check if this file should be skipped
    if (this->UicSkip(uiInputFile)) {
      continue;
    }
    // Check if the job already exists
    bool jobExists = false;
    for (const auto& job : this->UicJobs) {
      if ((job->SourceFile == uiInputFile) &&
          (job->IncludeString == includeString)) {
        jobExists = true;
        break;
      }
    }
    if (!jobExists) {
      auto job = cm::make_unique<UicJob>();
      job->SourceFile = uiInputFile;
      job->BuildFileRel = this->AutogenIncludeDir;
      job->BuildFileRel += includeString;
      job->Includer = absFilename;
      job->IncludeString = includeString;
      this->UicJobs.push_back(std::move(job));
    }
  }

  return true;
}

bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile,
                                             std::string const& sourceFile,
                                             std::string const& includeString)
{
  bool success = false;
  std::string searchFile =
    cmSystemTools::GetFilenameWithoutLastExtension(includeString).substr(3);
  searchFile += ".ui";
  // Collect search paths list
  std::vector<std::string> testFiles;
  {
    std::string const searchPath = SubDirPrefix(includeString);

    std::string searchFileFull;
    if (!searchPath.empty()) {
      searchFileFull = searchPath;
      searchFileFull += searchFile;
    }
    // Vicinity of the source
    {
      std::string const sourcePath = SubDirPrefix(sourceFile);
      testFiles.push_back(sourcePath + searchFile);
      if (!searchPath.empty()) {
        testFiles.push_back(sourcePath + searchFileFull);
      }
    }
    // AUTOUIC search paths
    if (!this->UicSearchPaths.empty()) {
      for (std::string const& sPath : this->UicSearchPaths) {
        testFiles.push_back((sPath + "/").append(searchFile));
      }
      if (!searchPath.empty()) {
        for (std::string const& sPath : this->UicSearchPaths) {
          testFiles.push_back((sPath + "/").append(searchFileFull));
        }
      }
    }
  }

  // Search for the .ui file!
  for (std::string const& testFile : testFiles) {
    if (cmSystemTools::FileExists(testFile.c_str())) {
      absFile = cmSystemTools::GetRealPath(testFile);
      success = true;
      break;
    }
  }

  // Log error
  if (!success) {
    std::string emsg = "Could not find ";
    emsg += cmQtAutoGen::Quoted(searchFile);
    emsg += " in\n";
    for (std::string const& testFile : testFiles) {
      emsg += "  ";
      emsg += cmQtAutoGen::Quoted(testFile);
      emsg += "\n";
    }
    this->LogFileError(cmQtAutoGen::UIC, sourceFile, emsg);
  }

  return success;
}

bool cmQtAutoGenerators::UicGenerateAll()
{
  if (!this->UicEnabled()) {
    return true;
  }

  // Look for name collisions in included uic files
  {
    bool collision = false;
    std::map<std::string, std::vector<UicJob const*>> collisions;
    for (auto const& job : this->UicJobs) {
      auto& list = collisions[job->IncludeString];
      if (!list.empty()) {
        collision = true;
      }
      list.push_back(job.get());
    }
    if (collision) {
      std::string emsg =
        "Included uic files with the same name will be "
        "generated from different sources.\n"
        "Consider 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"
        "Include conflicts\n"
        "-----------------\n";
      const auto& colls = collisions;
      for (auto const& coll : colls) {
        if (coll.second.size() > 1) {
          emsg += cmQtAutoGen::Quoted(coll.first);
          emsg += " included in\n";
          for (const UicJob* job : coll.second) {
            emsg += " - ";
            emsg += cmQtAutoGen::Quoted(job->Includer);
            emsg += "\n";
          }
          emsg += "would be generated from\n";
          for (const UicJob* job : coll.second) {
            emsg += " - ";
            emsg += cmQtAutoGen::Quoted(job->SourceFile);
            emsg += "\n";
          }
        }
      }
      this->LogError(cmQtAutoGen::UIC, emsg);
      return false;
    }
  }

  // Generate ui header files
  for (const auto& item : this->UicJobs) {
    if (!this->UicGenerateFile(*item)) {
      return false;
    }
  }

  return true;
}

/**
 * @return True on success
 */
bool cmQtAutoGenerators::UicGenerateFile(const UicJob& uicJob)
{
  bool success = true;

  std::string const uicFileAbs = cmSystemTools::CollapseCombinedPath(
    this->AutogenBuildDir, uicJob.BuildFileRel);

  bool generate = false;
  std::string generateReason;
  if (!generate && !cmSystemTools::FileExists(uicFileAbs.c_str())) {
    if (this->Verbose) {
      generateReason = "Generating ";
      generateReason += cmQtAutoGen::Quoted(uicFileAbs);
      generateReason += " from its source file ";
      generateReason += cmQtAutoGen::Quoted(uicJob.SourceFile);
      generateReason += " because it doesn't exist";
    }
    generate = true;
  }
  if (!generate && this->UicSettingsChanged) {
    if (this->Verbose) {
      generateReason = "Generating ";
      generateReason += cmQtAutoGen::Quoted(uicFileAbs);
      generateReason += " from ";
      generateReason += cmQtAutoGen::Quoted(uicJob.SourceFile);
      generateReason += " because the UIC settings changed";
    }
    generate = true;
  }
  if (!generate) {
    std::string error;
    if (FileIsOlderThan(uicFileAbs, uicJob.SourceFile, &error)) {
      if (this->Verbose) {
        generateReason = "Generating ";
        generateReason += cmQtAutoGen::Quoted(uicFileAbs);
        generateReason += " because it's older than its source file ";
        generateReason += cmQtAutoGen::Quoted(uicJob.SourceFile);
      }
      generate = true;
    } else {
      if (!error.empty()) {
        this->LogError(cmQtAutoGen::UIC, error);
        success = false;
      }
    }
  }
  if (generate) {
    // Log
    if (this->Verbose) {
      this->LogBold("Generating UIC header " + uicJob.BuildFileRel);
      this->LogInfo(cmQtAutoGen::UIC, generateReason);
    }

    // Make sure the parent directory exists
    if (this->MakeParentDirectory(cmQtAutoGen::UIC, uicFileAbs)) {
      // Compose uic command
      std::vector<std::string> cmd;
      cmd.push_back(this->UicExecutable);
      {
        std::vector<std::string> allOpts = this->UicTargetOptions;
        auto optionIt = this->UicOptions.find(uicJob.SourceFile);
        if (optionIt != this->UicOptions.end()) {
          cmQtAutoGen::UicMergeOptions(allOpts, optionIt->second,
                                       (this->QtMajorVersion == "5"));
        }
        cmd.insert(cmd.end(), allOpts.begin(), allOpts.end());
      }
      cmd.push_back("-o");
      cmd.push_back(uicFileAbs);
      cmd.push_back(uicJob.SourceFile);

      std::string output;
      if (this->RunCommand(cmd, output)) {
        // Success
      } else {
        // Command failed
        {
          std::string emsg = "uic failed for\n  ";
          emsg += cmQtAutoGen::Quoted(uicJob.SourceFile);
          emsg += "\nincluded by\n  ";
          emsg += cmQtAutoGen::Quoted(uicJob.Includer);
          this->LogCommandError(cmQtAutoGen::UIC, emsg, cmd, output);
        }
        cmSystemTools::RemoveFile(uicFileAbs);
        success = false;
      }
    } else {
      // Parent directory creation failed
      success = false;
    }
  }
  return success;
}

bool cmQtAutoGenerators::RccGenerateAll()
{
  if (!this->RccEnabled()) {
    return true;
  }

  // Generate rcc files
  for (const RccJob& rccJob : this->RccJobs) {
    if (!this->RccGenerateFile(rccJob)) {
      return false;
    }
  }
  return true;
}

/**
 * @return True on success
 */
bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob)
{
  bool success = true;
  bool rccGenerated = false;

  std::string rccFileAbs;
  if (this->MultiConfig == cmQtAutoGen::SINGLE) {
    rccFileAbs = rccJob.RccFile;
  } else {
    rccFileAbs =
      cmQtAutoGen::AppendFilenameSuffix(rccJob.RccFile, this->ConfigSuffix);
  }
  std::string const rccFileRel = cmSystemTools::RelativePath(
    this->AutogenBuildDir.c_str(), rccFileAbs.c_str());

  // Check if regeneration is required
  bool generate = false;
  std::string generateReason;
  if (!cmSystemTools::FileExists(rccJob.QrcFile)) {
    {
      std::string error = "Could not find the file\n  ";
      error += cmQtAutoGen::Quoted(rccJob.QrcFile);
      this->LogError(cmQtAutoGen::RCC, error);
    }
    success = false;
  }
  if (success && !generate && !cmSystemTools::FileExists(rccFileAbs.c_str())) {
    if (this->Verbose) {
      generateReason = "Generating ";
      generateReason += cmQtAutoGen::Quoted(rccFileAbs);
      generateReason += " from its source file ";
      generateReason += cmQtAutoGen::Quoted(rccJob.QrcFile);
      generateReason += " because it doesn't exist";
    }
    generate = true;
  }
  if (success && !generate && this->RccSettingsChanged) {
    if (this->Verbose) {
      generateReason = "Generating ";
      generateReason += cmQtAutoGen::Quoted(rccFileAbs);
      generateReason += " from ";
      generateReason += cmQtAutoGen::Quoted(rccJob.QrcFile);
      generateReason += " because the RCC settings changed";
    }
    generate = true;
  }
  if (success && !generate) {
    std::string error;
    if (FileIsOlderThan(rccFileAbs, rccJob.QrcFile, &error)) {
      if (this->Verbose) {
        generateReason = "Generating ";
        generateReason += cmQtAutoGen::Quoted(rccFileAbs);
        generateReason += " because it is older than ";
        generateReason += cmQtAutoGen::Quoted(rccJob.QrcFile);
      }
      generate = true;
    } else {
      if (!error.empty()) {
        this->LogError(cmQtAutoGen::RCC, error);
        success = false;
      }
    }
  }
  if (success && !generate) {
    // Acquire input file list
    std::vector<std::string> readFiles;
    std::vector<std::string> const* files = nullptr;
    if (!rccJob.Inputs.empty()) {
      files = &rccJob.Inputs;
    } else {
      // Read input file list from qrc file
      std::string error;
      if (cmQtAutoGen::RccListInputs(this->QtMajorVersion, this->RccExecutable,
                                     rccJob.QrcFile, readFiles, &error)) {
        files = &readFiles;
      } else {
        this->LogFileError(cmQtAutoGen::RCC, rccJob.QrcFile, error);
        success = false;
      }
    }
    // Test if any input file is newer than the build file
    if (files != nullptr) {
      std::string error;
      for (std::string const& resFile : *files) {
        if (!cmSystemTools::FileExists(resFile.c_str())) {
          error = "Could not find the file\n  ";
          error += cmQtAutoGen::Quoted(resFile);
          error += "\nwhich is listed in\n  ";
          error += cmQtAutoGen::Quoted(rccJob.QrcFile);
          break;
        }
        if (FileIsOlderThan(rccFileAbs, resFile, &error)) {
          if (this->Verbose) {
            generateReason = "Generating ";
            generateReason += cmQtAutoGen::Quoted(rccFileAbs);
            generateReason += " from ";
            generateReason += cmQtAutoGen::Quoted(rccJob.QrcFile);
            generateReason += " because it is older than ";
            generateReason += cmQtAutoGen::Quoted(resFile);
          }
          generate = true;
          break;
        }
        if (!error.empty()) {
          break;
        }
      }
      // Print error
      if (!error.empty()) {
        this->LogError(cmQtAutoGen::RCC, error);
        success = false;
      }
    }
  }
  // Regenerate on demand
  if (generate) {
    // Log
    if (this->Verbose) {
      this->LogBold("Generating RCC source " + rccFileRel);
      this->LogInfo(cmQtAutoGen::RCC, generateReason);
    }

    // Make sure the parent directory exists
    if (this->MakeParentDirectory(cmQtAutoGen::RCC, rccFileAbs)) {
      // Compose rcc command
      std::vector<std::string> cmd;
      cmd.push_back(this->RccExecutable);
      cmd.insert(cmd.end(), rccJob.Options.begin(), rccJob.Options.end());
      cmd.push_back("-o");
      cmd.push_back(rccFileAbs);
      cmd.push_back(rccJob.QrcFile);

      std::string output;
      if (this->RunCommand(cmd, output)) {
        // Success
        rccGenerated = true;
      } else {
        {
          std::string emsg = "rcc failed for\n  ";
          emsg += cmQtAutoGen::Quoted(rccJob.QrcFile);
          this->LogCommandError(cmQtAutoGen::RCC, emsg, cmd, output);
        }
        cmSystemTools::RemoveFile(rccFileAbs);
        success = false;
      }
    } else {
      // Parent directory creation failed
      success = false;
    }
  }

  // Generate a wrapper source file on demand
  if (success && (this->MultiConfig == cmQtAutoGen::WRAP)) {
    // Wrapper file name
    std::string const& wrapperFileAbs = rccJob.RccFile;
    std::string const wrapperFileRel = cmSystemTools::RelativePath(
      this->AutogenBuildDir.c_str(), wrapperFileAbs.c_str());
    // Wrapper file content
    std::string content = "// This is an autogenerated configuration "
                          "wrapper file. Changes will be overwritten.\n"
                          "#include \"";
    content += cmSystemTools::GetFilenameName(rccFileRel);
    content += "\"\n";
    // Write content to file
    if (this->FileDiffers(wrapperFileAbs, content)) {
      // Write new wrapper file
      if (this->Verbose) {
        this->LogBold("Generating RCC wrapper " + wrapperFileRel);
      }
      if (!this->FileWrite(cmQtAutoGen::RCC, wrapperFileAbs, content)) {
        this->LogFileError(cmQtAutoGen::RCC, wrapperFileAbs,
                           "rcc wrapper file writing failed");
        success = false;
      }
    } else if (rccGenerated) {
      // Just touch the wrapper file
      if (this->Verbose) {
        this->LogInfo(cmQtAutoGen::RCC,
                      "Touching RCC wrapper " + wrapperFileRel);
      }
      cmSystemTools::Touch(wrapperFileAbs, false);
    }
  }

  return success;
}

void cmQtAutoGenerators::LogBold(std::string const& message) const
{
  cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue |
                                     cmsysTerminal_Color_ForegroundBold,
                                   message.c_str(), true, this->ColorOutput);
}

void cmQtAutoGenerators::LogInfo(cmQtAutoGen::Generator genType,
                                 std::string const& message) const
{
  std::string msg = cmQtAutoGen::GeneratorName(genType);
  msg += ": ";
  msg += message;
  if (msg.back() != '\n') {
    msg.push_back('\n');
  }
  cmSystemTools::Stdout(msg.c_str(), msg.size());
}

void cmQtAutoGenerators::LogWarning(cmQtAutoGen::Generator genType,
                                    std::string const& message) const
{
  std::string msg = cmQtAutoGen::GeneratorName(genType);
  msg += " warning:";
  if (message.find('\n') == std::string::npos) {
    // Single line message
    msg.push_back(' ');
  } else {
    // Multi line message
    msg.push_back('\n');
  }
  // Message
  msg += message;
  if (msg.back() != '\n') {
    msg.push_back('\n');
  }
  msg.push_back('\n');
  cmSystemTools::Stdout(msg.c_str(), msg.size());
}

void cmQtAutoGenerators::LogFileWarning(cmQtAutoGen::Generator genType,
                                        std::string const& filename,
                                        std::string const& message) const
{
  std::string msg = "  ";
  msg += cmQtAutoGen::Quoted(filename);
  msg.push_back('\n');
  // Message
  msg += message;
  this->LogWarning(genType, msg);
}

void cmQtAutoGenerators::LogError(cmQtAutoGen::Generator genType,
                                  std::string const& message) const
{
  std::string msg;
  msg.push_back('\n');
  msg += HeadLine(cmQtAutoGen::GeneratorName(genType) + " error");
  // Message
  msg += message;
  if (msg.back() != '\n') {
    msg.push_back('\n');
  }
  msg.push_back('\n');
  cmSystemTools::Stderr(msg.c_str(), msg.size());
}

void cmQtAutoGenerators::LogFileError(cmQtAutoGen::Generator genType,
                                      std::string const& filename,
                                      std::string const& message) const
{
  std::string emsg = "  ";
  emsg += cmQtAutoGen::Quoted(filename);
  emsg += '\n';
  // Message
  emsg += message;
  this->LogError(genType, emsg);
}

void cmQtAutoGenerators::LogCommandError(
  cmQtAutoGen::Generator genType, std::string const& message,
  std::vector<std::string> const& command, std::string const& output) const
{
  std::string msg;
  msg.push_back('\n');
  msg += HeadLine(cmQtAutoGen::GeneratorName(genType) + " subprocess error");
  msg += message;
  if (msg.back() != '\n') {
    msg.push_back('\n');
  }
  msg.push_back('\n');
  msg += HeadLine("Command");
  msg += QuotedCommand(command);
  if (msg.back() != '\n') {
    msg.push_back('\n');
  }
  msg.push_back('\n');
  msg += HeadLine("Output");
  msg += output;
  if (msg.back() != '\n') {
    msg.push_back('\n');
  }
  msg.push_back('\n');
  cmSystemTools::Stderr(msg.c_str(), msg.size());
}

/**
 * @brief Generates the parent directory of the given file on demand
 * @return True on success
 */
bool cmQtAutoGenerators::MakeParentDirectory(cmQtAutoGen::Generator genType,
                                             std::string const& filename) const
{
  bool success = true;
  std::string const dirName = cmSystemTools::GetFilenamePath(filename);
  if (!dirName.empty()) {
    if (!cmSystemTools::MakeDirectory(dirName)) {
      this->LogFileError(genType, filename,
                         "Could not create parent directory");
      success = false;
    }
  }
  return success;
}

bool cmQtAutoGenerators::FileDiffers(std::string const& filename,
                                     std::string const& content)
{
  bool differs = true;
  {
    std::string oldContents;
    if (ReadFile(oldContents, filename)) {
      differs = (oldContents != content);
    }
  }
  return differs;
}

bool cmQtAutoGenerators::FileWrite(cmQtAutoGen::Generator genType,
                                   std::string const& filename,
                                   std::string const& content)
{
  std::string error;
  // Make sure the parent directory exists
  if (this->MakeParentDirectory(genType, filename)) {
    cmsys::ofstream outfile;
    outfile.open(filename.c_str(),
                 (std::ios::out | std::ios::binary | std::ios::trunc));
    if (outfile) {
      outfile << content;
      // Check for write errors
      if (!outfile.good()) {
        error = "File writing failed";
      }
    } else {
      error = "Opening file for writing failed";
    }
  }
  if (!error.empty()) {
    this->LogFileError(genType, filename, error);
    return false;
  }
  return true;
}

/**
 * @brief Runs a command and returns true on success
 * @return True on success
 */
bool cmQtAutoGenerators::RunCommand(std::vector<std::string> const& command,
                                    std::string& output) const
{
  // Log command
  if (this->Verbose) {
    std::string qcmd = QuotedCommand(command);
    qcmd.push_back('\n');
    cmSystemTools::Stdout(qcmd.c_str(), qcmd.size());
  }
  // Execute command
  int retVal = 0;
  bool res = cmSystemTools::RunSingleCommand(
    command, &output, &output, &retVal, nullptr, cmSystemTools::OUTPUT_NONE);
  return (res && (retVal == 0));
}

/**
 * @brief Tries to find the header file to the given file base path by
 * appending different header extensions
 * @return True on success
 */
bool cmQtAutoGenerators::FindHeader(std::string& header,
                                    std::string const& testBasePath) const
{
  for (std::string const& ext : this->HeaderExtensions) {
    std::string testFilePath(testBasePath);
    testFilePath.push_back('.');
    testFilePath += ext;
    if (cmSystemTools::FileExists(testFilePath.c_str())) {
      header = testFilePath;
      return true;
    }
  }
  return false;
}
