summaryrefslogtreecommitdiff
path: root/Source/cmQtAutoGenerator.h
blob: 5c3a8adccb4980ce162ec3845900555cefc7acf7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#pragma once

#include "cmConfigure.h" // IWYU pragma: keep

#include <istream>
#include <mutex>
#include <string>
#include <unordered_set>
#include <vector>

#include <cm/string_view>

#include <cm3p/json/value.h>

#include "cmFileTime.h"
#include "cmQtAutoGen.h"

/** \class cmQtAutoGenerator
 * \brief Base class for QtAutoGen generators
 */
class cmQtAutoGenerator : public cmQtAutoGen
{
public:
  // -- Types

  /** Thread safe logger.  */
  class Logger
  {
  public:
    // -- Construction
    Logger();
    ~Logger() = default;
    // -- Verbosity
    unsigned int Verbosity() const { return this->Verbosity_; }
    void SetVerbosity(unsigned int value) { this->Verbosity_ = value; }
    void RaiseVerbosity(unsigned int value);
    bool Verbose() const { return (this->Verbosity_ != 0); }
    void SetVerbose(bool value) { this->Verbosity_ = value ? 1 : 0; }
    // -- Color output
    bool ColorOutput() const { return this->ColorOutput_; }
    void SetColorOutput(bool value);
    // -- Log info
    void Info(GenT genType, cm::string_view message) const;
    // -- Log warning
    void Warning(GenT genType, cm::string_view message) const;
    // -- Log error
    void Error(GenT genType, cm::string_view message) const;
    void ErrorCommand(GenT genType, cm::string_view message,
                      std::vector<std::string> const& command,
                      std::string const& output) const;

  private:
    static std::string HeadLine(cm::string_view title);

    mutable std::mutex Mutex_;
    unsigned int Verbosity_ = 0;
    bool ColorOutput_ = false;
  };

  /** Project directories.  */
  struct ProjectDirsT
  {
    std::string Source;
    std::string Binary;
    std::string CurrentSource;
    std::string CurrentBinary;
  };

  // -- File system methods
  static bool MakeParentDirectory(std::string const& filename);
  static bool FileRead(std::string& content, std::string const& filename,
                       std::string* error = nullptr);
  static bool FileWrite(std::string const& filename,
                        std::string const& content,
                        std::string* error = nullptr);
  static bool FileDiffers(std::string const& filename,
                          std::string const& content);

  // -- Constructors
  cmQtAutoGenerator(GenT genType);
  virtual ~cmQtAutoGenerator();

  cmQtAutoGenerator(cmQtAutoGenerator const&) = delete;
  cmQtAutoGenerator& operator=(cmQtAutoGenerator const&) = delete;

  // -- Info options
  std::string const& InfoFile() const { return this->InfoFile_; }
  std::string const& InfoDir() const { return this->InfoDir_; }
  cmFileTime const& InfoFileTime() const { return this->InfoFileTime_; }
  std::string const& InfoConfig() const { return this->InfoConfig_; }

  // -- Info file parsing
  /** Info file reader class. */
  class InfoT
  {
  public:
    InfoT(cmQtAutoGenerator& gen)
      : Gen_(gen)
    {
    }

    /** Read json data from a stream.  */
    bool Read(std::istream& istr);

    /** Returns false if the JSON value isn't a string.  */
    bool GetString(std::string const& key, std::string& value,
                   bool required) const;
    bool GetStringConfig(std::string const& key, std::string& value,
                         bool required) const;
    bool GetBool(std::string const& key, bool& value, bool required) const;
    bool GetUInt(std::string const& key, unsigned int& value,
                 bool required) const;
    /** Returns false if the JSON value isn't an array.  */
    bool GetArray(std::string const& key, std::vector<std::string>& list,
                  bool required) const;
    bool GetArray(std::string const& key,
                  std::unordered_set<std::string>& list, bool required) const;
    bool GetArrayConfig(std::string const& key, std::vector<std::string>& list,
                        bool required) const;

    Json::Value const& GetValue(std::string const& key) const
    {
      return this->Json_[key];
    }

    /** Returns true if strings were appended to the list.  */
    static bool GetJsonArray(std::vector<std::string>& list,
                             Json::Value const& jval);
    /** Returns true if strings were found in the JSON array.  */
    static bool GetJsonArray(std::unordered_set<std::string>& list,
                             Json::Value const& jval);

    bool LogError(GenT genType, cm::string_view message) const;
    bool LogError(cm::string_view message) const;

  private:
    std::string ConfigKey(cm::string_view key) const;

    Json::Value Json_;
    cmQtAutoGenerator& Gen_;
  };

  // -- Settings file
  static std::string SettingsFind(cm::string_view content,
                                  cm::string_view key);

  // -- Directories
  ProjectDirsT const& ProjectDirs() const { return this->ProjectDirs_; }
  std::string MessagePath(cm::string_view path) const;

  // -- Run
  bool Run(cm::string_view infoFile, cm::string_view config);

protected:
  // -- Abstract processing interface
  virtual bool InitFromInfo(InfoT const& info) = 0;
  virtual bool Process() = 0;
  // - Utility classes
  Logger const& Log() const { return this->Logger_; }

private:
  // -- Generator type
  GenT GenType_;
  // -- Logging
  Logger Logger_;
  // -- Info file
  std::string InfoFile_;
  std::string InfoDir_;
  cmFileTime InfoFileTime_;
  std::string InfoConfig_;
  // -- Directories
  ProjectDirsT ProjectDirs_;
};