~bzoltan/kubuntu-packaging/decouple_cmake_plugin

« back to all changes in this revision

Viewing changes to src/shared/qbs/src/lib/buildgraph/automoc.cpp

  • Committer: Timo Jyrinki
  • Date: 2013-11-15 12:25:23 UTC
  • mfrom: (1.1.28)
  • Revision ID: timo.jyrinki@canonical.com-20131115122523-i2kyamsu4gs2mu1m
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
namespace qbs {
45
45
namespace Internal {
46
46
 
47
 
static char **createCFileTags(const FileTags &fileTags)
48
 
{
49
 
    if (fileTags.isEmpty())
50
 
        return 0;
51
 
 
52
 
    char **buf = new char*[fileTags.count()];
53
 
    size_t i = 0;
54
 
    foreach (const FileTag &fileTag, fileTags) {
55
 
        buf[i] = qstrdup(fileTag.toString().toLocal8Bit().data());
56
 
        ++i;
57
 
    }
58
 
    return buf;
59
 
}
60
 
 
61
 
static void freeCFileTags(char **cFileTags, int numFileTags)
62
 
{
63
 
    if (!cFileTags)
64
 
        return;
65
 
    for (int i = numFileTags; --i >= 0;)
66
 
        delete[] cFileTags[i];
67
 
    delete[] cFileTags;
68
 
}
69
 
 
70
47
AutoMoc::AutoMoc(const Logger &logger, QObject *parent)
71
48
    : QObject(parent)
72
49
    , m_scanResultCache(0)
81
58
 
82
59
void AutoMoc::apply(const ResolvedProductPtr &product)
83
60
{
84
 
    if (scanners().isEmpty())
 
61
    if (cppScanners().isEmpty() || hppScanners().isEmpty())
85
62
        throw ErrorInfo("C++ scanner cannot be loaded.");
86
63
 
87
64
    Artifact *pluginMetaDataFile = 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) {
159
136
    }
160
137
 
161
138
    if (pchFile)
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;
203
180
}
204
181
 
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)
206
184
{
207
185
    if (m_logger.traceEnabled())
208
186
        m_logger.qbsTrace() << "[AUTOMOC] checks " << relativeArtifactFileName(artifact);
209
187
 
210
188
    hasQObjectMacro = false;
211
 
    const int numFileTags = artifact->fileTags.count();
212
 
    char **cFileTags = createCFileTags(artifact->fileTags);
213
 
 
214
 
    foreach (ScannerPlugin *scanner, scanners()) {
215
 
        void *opaq = scanner->open(artifact->filePath().utf16(), cFileTags, numFileTags);
216
 
        if (!opaq || !scanner->additionalFileTags)
217
 
            continue;
218
 
 
219
 
        // HACK: misuse the file dependency scanner as provider for file tags
220
 
        int length = 0;
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;
232
 
            }
233
 
        }
234
 
 
235
 
        scanner->close(opaq);
236
 
 
237
 
        ScanResultCache::Result scanResult;
238
 
        if (m_scanResultCache)
239
 
            scanResult = m_scanResultCache->value(artifact->filePath());
 
189
 
 
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);
243
 
            if (!opaq)
 
194
            void *opaq = scanner->open(artifact->filePath().utf16(),
 
195
                                       ScanForDependenciesFlag | ScanForFileTagsFlag);
 
196
            if (!opaq || !scanner->additionalFileTags)
244
197
                continue;
245
198
 
 
199
            int length = 0;
 
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];
 
204
            }
 
205
 
246
206
            forever {
247
207
                int flags = 0;
248
208
                const char *szOutFilePath = scanner->next(opaq, &length, &flags);
256
216
            }
257
217
 
258
218
            scanner->close(opaq);
259
 
            if (m_scanResultCache)
260
 
                m_scanResultCache->insert(artifact->filePath(), scanResult);
 
219
            m_scanResultCache->insert(artifact->filePath(), scanResult);
 
220
        }
 
221
 
 
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";
 
228
            }
261
229
        }
262
230
 
263
231
        foreach (const ScanResultCache::Dependency &dependency, scanResult.deps) {
269
237
            }
270
238
        }
271
239
    }
272
 
 
273
 
    freeCFileTags(cFileTags, numFileTags);
274
240
}
275
241
 
276
242
static FileTags provideMocHeaderFileTags()
346
312
                                    << relativeArtifactFileName(mocObjArtifact);
347
313
            }
348
314
            project->buildData->removeArtifact(mocObjArtifact, m_logger);
 
315
            delete mocObjArtifact;
349
316
        }
350
317
    }
351
318
 
357
324
    delete generatedMocArtifact;
358
325
}
359
326
 
360
 
QList<ScannerPlugin *> AutoMoc::scanners() const
361
 
{
362
 
    if (m_scanners.isEmpty())
363
 
        m_scanners = ScannerPluginManager::scannersForFileTag("hpp");
364
 
 
365
 
    return m_scanners;
 
327
const QList<ScannerPlugin *> &AutoMoc::cppScanners() const
 
328
{
 
329
    if (m_cppScanners.isEmpty())
 
330
        m_cppScanners = ScannerPluginManager::scannersForFileTag("cpp");
 
331
 
 
332
    return m_cppScanners;
 
333
}
 
334
 
 
335
const QList<ScannerPlugin *> &AutoMoc::hppScanners() const
 
336
{
 
337
    if (m_hppScanners.isEmpty())
 
338
        m_hppScanners = ScannerPluginManager::scannersForFileTag("hpp");
 
339
 
 
340
    return m_hppScanners;
366
341
}
367
342
 
368
343
} // namespace Internal