45
45
namespace Internal {
47
static char **createCFileTags(const FileTags &fileTags)
49
if (fileTags.isEmpty())
52
char **buf = new char*[fileTags.count()];
54
foreach (const FileTag &fileTag, fileTags) {
55
buf[i] = qstrdup(fileTag.toString().toLocal8Bit().data());
61
static void freeCFileTags(char **cFileTags, int numFileTags)
65
for (int i = numFileTags; --i >= 0;)
66
delete[] cFileTags[i];
70
47
AutoMoc::AutoMoc(const Logger &logger, QObject *parent)
72
49
, m_scanResultCache(0)
94
71
Artifact *artifact = *it;
95
72
if (!pchFile || !pluginMetaDataFile) {
96
73
foreach (const FileTag &fileTag, artifact->fileTags) {
97
if (fileTag == "c++_pch")
74
if (fileTag == "cpp_pch")
98
75
pchFile = artifact;
99
76
else if (fileTag == "qt_plugin_metadata")
100
77
pluginMetaDataFile = artifact;
119
96
FileTag mocFileTag;
120
97
bool alreadyMocced = isVictimOfMoc(artifact, fileType, mocFileTag);
121
98
bool hasQObjectMacro;
122
scan(artifact, hasQObjectMacro, includedMocCppFiles);
99
scan(artifact, fileType, hasQObjectMacro, includedMocCppFiles);
123
100
if (hasQObjectMacro && !alreadyMocced) {
124
101
artifactsToMoc += qMakePair(artifact, fileType);
125
102
} else if (!hasQObjectMacro && alreadyMocced) {
162
artifactsPerFileTag["c++_pch"] += pchFile;
139
artifactsPerFileTag["cpp_pch"] += pchFile;
163
140
if (!artifactsPerFileTag.isEmpty()) {
164
141
emit reportCommandDescription(QLatin1String("automoc"),
165
142
Tr::tr("Applying moc rules for '%1'.")
202
179
return UnknownFileType;
205
void AutoMoc::scan(Artifact *artifact, bool &hasQObjectMacro, QSet<QString> &includedMocCppFiles)
182
void AutoMoc::scan(Artifact *artifact, FileType fileType, bool &hasQObjectMacro,
183
QSet<QString> &includedMocCppFiles)
207
185
if (m_logger.traceEnabled())
208
186
m_logger.qbsTrace() << "[AUTOMOC] checks " << relativeArtifactFileName(artifact);
210
188
hasQObjectMacro = false;
211
const int numFileTags = artifact->fileTags.count();
212
char **cFileTags = createCFileTags(artifact->fileTags);
214
foreach (ScannerPlugin *scanner, scanners()) {
215
void *opaq = scanner->open(artifact->filePath().utf16(), cFileTags, numFileTags);
216
if (!opaq || !scanner->additionalFileTags)
219
// HACK: misuse the file dependency scanner as provider for file tags
221
const char **szFileTagsFromScanner = scanner->additionalFileTags(opaq, &length);
222
if (szFileTagsFromScanner && length > 0) {
223
for (int i=length; --i >= 0;) {
224
artifact->fileTags.insert(szFileTagsFromScanner[i]);
225
if (m_logger.traceEnabled())
226
m_logger.qbsTrace() << "[AUTOMOC] finds Q_OBJECT macro";
227
const QByteArray fileTagFromScanner
228
= QByteArray::fromRawData(szFileTagsFromScanner[i],
229
qstrlen(szFileTagsFromScanner[i]));
230
if (fileTagFromScanner.startsWith("moc"))
231
hasQObjectMacro = true;
235
scanner->close(opaq);
237
ScanResultCache::Result scanResult;
238
if (m_scanResultCache)
239
scanResult = m_scanResultCache->value(artifact->filePath());
190
foreach (ScannerPlugin *scanner, fileType == HppFileType ? hppScanners() : cppScanners()) {
191
ScanResultCache::Result scanResult = m_scanResultCache->value(artifact->filePath());
240
192
if (!scanResult.valid) {
241
193
scanResult.valid = true;
242
opaq = scanner->open(artifact->filePath().utf16(), 0, 0);
194
void *opaq = scanner->open(artifact->filePath().utf16(),
195
ScanForDependenciesFlag | ScanForFileTagsFlag);
196
if (!opaq || !scanner->additionalFileTags)
200
const char **szFileTagsFromScanner = scanner->additionalFileTags(opaq, &length);
201
if (szFileTagsFromScanner && length > 0) {
202
for (int i = length; --i >= 0;)
203
scanResult.additionalFileTags += szFileTagsFromScanner[i];
248
208
const char *szOutFilePath = scanner->next(opaq, &length, &flags);
258
218
scanner->close(opaq);
259
if (m_scanResultCache)
260
m_scanResultCache->insert(artifact->filePath(), scanResult);
219
m_scanResultCache->insert(artifact->filePath(), scanResult);
222
foreach (const FileTag &tag, scanResult.additionalFileTags) {
223
artifact->fileTags.insert(tag);
224
if (tag.name().startsWith("moc")) {
225
hasQObjectMacro = true;
226
if (m_logger.traceEnabled())
227
m_logger.qbsTrace() << "[AUTOMOC] finds Q_OBJECT macro";
263
231
foreach (const ScanResultCache::Dependency &dependency, scanResult.deps) {
357
324
delete generatedMocArtifact;
360
QList<ScannerPlugin *> AutoMoc::scanners() const
362
if (m_scanners.isEmpty())
363
m_scanners = ScannerPluginManager::scannersForFileTag("hpp");
327
const QList<ScannerPlugin *> &AutoMoc::cppScanners() const
329
if (m_cppScanners.isEmpty())
330
m_cppScanners = ScannerPluginManager::scannersForFileTag("cpp");
332
return m_cppScanners;
335
const QList<ScannerPlugin *> &AutoMoc::hppScanners() const
337
if (m_hppScanners.isEmpty())
338
m_hppScanners = ScannerPluginManager::scannersForFileTag("hpp");
340
return m_hppScanners;
368
343
} // namespace Internal