Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
4
5#include <depfile_shared.h>
6#include "preprocessor.h"
7#include "moc.h"
8#include "outputrevision.h"
9#include "collectjson.h"
10
11#include <qfile.h>
12#include <qfileinfo.h>
13#include <qdir.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <ctype.h>
17#include <errno.h>
18
19#include <qcoreapplication.h>
20#include <qcommandlineoption.h>
21#include <qcommandlineparser.h>
22#include <qscopedpointer.h>
23
25
26using namespace Qt::StringLiterals;
27
28/*
29 This function looks at two file names and returns the name of the
30 infile with a path relative to outfile.
31
32 Examples:
33
34 /tmp/abc, /tmp/bcd -> abc
35 xyz/a/bc, xyz/b/ac -> ../a/bc
36 /tmp/abc, xyz/klm -> /tmp/abc
37 */
38
39static QByteArray combinePath(const QString &infile, const QString &outfile)
40{
41 QFileInfo inFileInfo(QDir::current(), infile);
42 QFileInfo outFileInfo(QDir::current(), outfile);
43 const QByteArray relativePath = QFile::encodeName(outFileInfo.dir().relativeFilePath(inFileInfo.filePath()));
44#ifdef Q_OS_WIN
45 // It's a system limitation.
46 // It depends on the Win API function which is used by the program to open files.
47 // cl apparently uses the functions that have the MAX_PATH limitation.
48 if (outFileInfo.dir().absolutePath().length() + relativePath.length() + 1 >= 260)
49 return QFile::encodeName(inFileInfo.absoluteFilePath());
50#endif
51 return relativePath;
52}
53
54
55void error(const char *msg = "Invalid argument")
56{
57 if (msg)
58 fprintf(stderr, "moc: %s\n", msg);
59}
60
62{
63 static inline void cleanup(FILE *handle) { if (handle) fclose(handle); }
64};
65
66static inline bool hasNext(const Symbols &symbols, int i)
67{ return (i < symbols.size()); }
68
69static inline const Symbol &next(const Symbols &symbols, int &i)
70{ return symbols.at(i++); }
71
72
75 int lineNum = 1;
76 Token last = PP_NOTOKEN;
77 Token secondlast = last;
78 int i = 0;
79 while (hasNext(symbols, i)) {
80 Symbol sym = next(symbols, i);
81 switch (sym.token) {
82 case PP_NEWLINE:
83 case PP_WHITESPACE:
84 if (last != PP_WHITESPACE) {
85 secondlast = last;
86 last = PP_WHITESPACE;
87 output += ' ';
88 }
89 continue;
91 if (last == PP_STRING_LITERAL)
92 output.chop(1);
93 else if (secondlast == PP_STRING_LITERAL && last == PP_WHITESPACE)
94 output.chop(2);
95 else
96 break;
97 output += sym.lexem().mid(1);
98 secondlast = last;
99 last = PP_STRING_LITERAL;
100 continue;
101 case MOC_INCLUDE_BEGIN:
102 lineNum = 0;
103 continue;
104 case MOC_INCLUDE_END:
105 lineNum = sym.lineNum;
106 continue;
107 default:
108 break;
109 }
110 secondlast = last;
111 last = sym.token;
112
113 const int padding = sym.lineNum - lineNum;
114 if (padding > 0) {
115 output.resize(output.size() + padding);
116 memset(output.data() + output.size() - padding, '\n', padding);
117 lineNum = sym.lineNum;
118 }
119
120 output += sym.lexem();
121 }
122
123 return output;
124}
125
127{
128 QStringList allArguments;
129 hasOptionFiles = false;
130 allArguments.reserve(arguments.size());
131 for (const QString &argument : arguments) {
132 // "@file" doesn't start with a '-' so we can't use QCommandLineParser for it
133 if (argument.startsWith(u'@')) {
134 QString optionsFile = argument;
135 optionsFile.remove(0, 1);
136 if (optionsFile.isEmpty()) {
137 error("The @ option requires an input file");
138 return QStringList();
139 }
140 QFile f(optionsFile);
142 error("Cannot open options file specified with @");
143 return QStringList();
144 }
145 hasOptionFiles = true;
146 while (!f.atEnd()) {
147 QString line = QString::fromLocal8Bit(f.readLine().trimmed());
148 if (!line.isEmpty())
149 allArguments << line;
150 }
151 } else {
152 allArguments << argument;
153 }
154 }
155 return allArguments;
156}
157
158int runMoc(int argc, char **argv)
159{
160 QCoreApplication app(argc, argv);
162
163 bool autoInclude = true;
164 bool defaultInclude = true;
165 Preprocessor pp;
166 Moc moc;
167 pp.macros["Q_MOC_RUN"];
168 pp.macros["__cplusplus"];
169
170 // Don't stumble over GCC extensions
171 Macro dummyVariadicFunctionMacro;
172 dummyVariadicFunctionMacro.isFunction = true;
173 dummyVariadicFunctionMacro.isVariadic = true;
174 dummyVariadicFunctionMacro.arguments += Symbol(0, PP_IDENTIFIER, "__VA_ARGS__");
175 pp.macros["__attribute__"] = dummyVariadicFunctionMacro;
176 pp.macros["__declspec"] = dummyVariadicFunctionMacro;
177
178 QString filename;
180 QFile in;
181 FILE *out = nullptr;
182
183 // Note that moc isn't translated.
184 // If you use this code as an example for a translated app, make sure to translate the strings.
185 QCommandLineParser parser;
186 parser.setApplicationDescription(QStringLiteral("Qt Meta Object Compiler version %1 (Qt %2)")
187 .arg(mocOutputRevision).arg(QString::fromLatin1(QT_VERSION_STR)));
188 parser.addHelpOption();
189 parser.addVersionOption();
191
192 QCommandLineOption outputOption(QStringLiteral("o"));
193 outputOption.setDescription(QStringLiteral("Write output to file rather than stdout."));
194 outputOption.setValueName(QStringLiteral("file"));
196 parser.addOption(outputOption);
197
198 QCommandLineOption includePathOption(QStringLiteral("I"));
199 includePathOption.setDescription(QStringLiteral("Add dir to the include path for header files."));
200 includePathOption.setValueName(QStringLiteral("dir"));
202 parser.addOption(includePathOption);
203
204 QCommandLineOption macFrameworkOption(QStringLiteral("F"));
205 macFrameworkOption.setDescription(QStringLiteral("Add Mac framework to the include path for header files."));
206 macFrameworkOption.setValueName(QStringLiteral("framework"));
208 parser.addOption(macFrameworkOption);
209
210 QCommandLineOption preprocessOption(QStringLiteral("E"));
211 preprocessOption.setDescription(QStringLiteral("Preprocess only; do not generate meta object code."));
212 parser.addOption(preprocessOption);
213
214 QCommandLineOption defineOption(QStringLiteral("D"));
215 defineOption.setDescription(QStringLiteral("Define macro, with optional definition."));
216 defineOption.setValueName(QStringLiteral("macro[=def]"));
218 parser.addOption(defineOption);
219
220 QCommandLineOption undefineOption(QStringLiteral("U"));
221 undefineOption.setDescription(QStringLiteral("Undefine macro."));
222 undefineOption.setValueName(QStringLiteral("macro"));
224 parser.addOption(undefineOption);
225
226 QCommandLineOption metadataOption(QStringLiteral("M"));
227 metadataOption.setDescription(QStringLiteral("Add key/value pair to plugin meta data"));
228 metadataOption.setValueName(QStringLiteral("key=value"));
230 parser.addOption(metadataOption);
231
232 QCommandLineOption compilerFlavorOption(QStringLiteral("compiler-flavor"));
233 compilerFlavorOption.setDescription(QStringLiteral("Set the compiler flavor: either \"msvc\" or \"unix\"."));
234 compilerFlavorOption.setValueName(QStringLiteral("flavor"));
235 parser.addOption(compilerFlavorOption);
236
237 QCommandLineOption noIncludeOption(QStringLiteral("i"));
238 noIncludeOption.setDescription(QStringLiteral("Do not generate an #include statement."));
239 parser.addOption(noIncludeOption);
240
241 QCommandLineOption pathPrefixOption(QStringLiteral("p"));
242 pathPrefixOption.setDescription(QStringLiteral("Path prefix for included file."));
243 pathPrefixOption.setValueName(QStringLiteral("path"));
245 parser.addOption(pathPrefixOption);
246
247 QCommandLineOption forceIncludeOption(QStringLiteral("f"));
248 forceIncludeOption.setDescription(QStringLiteral("Force #include <file> (overwrite default)."));
249 forceIncludeOption.setValueName(QStringLiteral("file"));
251 parser.addOption(forceIncludeOption);
252
253 QCommandLineOption prependIncludeOption(QStringLiteral("b"));
254 prependIncludeOption.setDescription(QStringLiteral("Prepend #include <file> (preserve default include)."));
255 prependIncludeOption.setValueName(QStringLiteral("file"));
257 parser.addOption(prependIncludeOption);
258
259 QCommandLineOption includeOption(QStringLiteral("include"));
260 includeOption.setDescription(QStringLiteral("Parse <file> as an #include before the main source(s)."));
261 includeOption.setValueName(QStringLiteral("file"));
262 parser.addOption(includeOption);
263
264 QCommandLineOption noNotesWarningsCompatOption(QStringLiteral("n"));
265 noNotesWarningsCompatOption.setDescription(QStringLiteral("Do not display notes (-nn) or warnings (-nw). Compatibility option."));
266 noNotesWarningsCompatOption.setValueName(QStringLiteral("which"));
267 noNotesWarningsCompatOption.setFlags(QCommandLineOption::ShortOptionStyle);
268 parser.addOption(noNotesWarningsCompatOption);
269
270 QCommandLineOption noNotesOption(QStringLiteral("no-notes"));
271 noNotesOption.setDescription(QStringLiteral("Do not display notes."));
272 parser.addOption(noNotesOption);
273
274 QCommandLineOption noWarningsOption(QStringLiteral("no-warnings"));
275 noWarningsOption.setDescription(QStringLiteral("Do not display warnings (implies --no-notes)."));
276 parser.addOption(noWarningsOption);
277
278 QCommandLineOption ignoreConflictsOption(QStringLiteral("ignore-option-clashes"));
279 ignoreConflictsOption.setDescription(QStringLiteral("Ignore all options that conflict with compilers, like -pthread conflicting with moc's -p option."));
280 parser.addOption(ignoreConflictsOption);
281
282 QCommandLineOption jsonOption(QStringLiteral("output-json"));
283 jsonOption.setDescription(QStringLiteral("In addition to generating C++ code, create a machine-readable JSON file in a file that matches the output file and an extra .json extension."));
284 parser.addOption(jsonOption);
285
286 QCommandLineOption debugIncludesOption(QStringLiteral("debug-includes"));
287 debugIncludesOption.setDescription(QStringLiteral("Display debug messages of each considered include path."));
288 parser.addOption(debugIncludesOption);
289
290 QCommandLineOption collectOption(QStringLiteral("collect-json"));
291 collectOption.setDescription(QStringLiteral("Instead of processing C++ code, collect previously generated JSON output into a single file."));
292 parser.addOption(collectOption);
293
294 QCommandLineOption depFileOption(QStringLiteral("output-dep-file"));
295 depFileOption.setDescription(
296 QStringLiteral("Output a Make-style dep file for build system consumption."));
297 parser.addOption(depFileOption);
298
299 QCommandLineOption depFilePathOption(QStringLiteral("dep-file-path"));
300 depFilePathOption.setDescription(QStringLiteral("Path where to write the dep file."));
301 depFilePathOption.setValueName(QStringLiteral("file"));
302 parser.addOption(depFilePathOption);
303
304 QCommandLineOption depFileRuleNameOption(QStringLiteral("dep-file-rule-name"));
305 depFileRuleNameOption.setDescription(
306 QStringLiteral("The rule name (first line) of the dep file."));
307 depFileRuleNameOption.setValueName(QStringLiteral("rule name"));
308 parser.addOption(depFileRuleNameOption);
309
310 QCommandLineOption requireCompleTypesOption(QStringLiteral("require-complete-types"));
311 requireCompleTypesOption.setDescription(QStringLiteral("Require complete types for better performance"));
312 parser.addOption(requireCompleTypesOption);
313
314 parser.addPositionalArgument(QStringLiteral("[header-file]"),
315 QStringLiteral("Header file to read from, otherwise stdin."));
316 parser.addPositionalArgument(QStringLiteral("[@option-file]"),
317 QStringLiteral("Read additional options from option-file."));
318 parser.addPositionalArgument(QStringLiteral("[MOC generated json file]"),
319 QStringLiteral("MOC generated json output"));
320
321 bool hasOptionFiles = false;
323 if (arguments.isEmpty())
324 return 1;
325
326 parser.process(arguments);
327
328 const QStringList files = parser.positionalArguments();
329 output = parser.value(outputOption);
330 if (parser.isSet(collectOption))
331 return collectJson(files, output, hasOptionFiles);
332
333 if (files.size() > 1) {
334 error(qPrintable("Too many input files specified: '"_L1 + files.join("' '"_L1) + u'\''));
335 parser.showHelp(1);
336 } else if (!files.isEmpty()) {
337 filename = files.first();
338 }
339
340 const bool ignoreConflictingOptions = parser.isSet(ignoreConflictsOption);
341 pp.preprocessOnly = parser.isSet(preprocessOption);
342 pp.setDebugIncludes(parser.isSet(debugIncludesOption));
343 if (parser.isSet(noIncludeOption)) {
344 moc.noInclude = true;
345 autoInclude = false;
346 }
347 if (parser.isSet(requireCompleTypesOption))
348 moc.requireCompleteTypes = true;
349 if (!ignoreConflictingOptions) {
350 if (parser.isSet(forceIncludeOption)) {
351 moc.noInclude = false;
352 autoInclude = false;
353 const auto forceIncludes = parser.values(forceIncludeOption);
354 for (const QString &include : forceIncludes) {
355 moc.includeFiles.append(QFile::encodeName(include));
356 defaultInclude = false;
357 }
358 }
359 const auto prependIncludes = parser.values(prependIncludeOption);
360 for (const QString &include : prependIncludes)
361 moc.includeFiles.prepend(QFile::encodeName(include));
362 if (parser.isSet(pathPrefixOption))
363 moc.includePath = QFile::encodeName(parser.value(pathPrefixOption));
364 }
365
366 const auto includePaths = parser.values(includePathOption);
367 for (const QString &path : includePaths)
369 QString compilerFlavor = parser.value(compilerFlavorOption);
370 if (compilerFlavor.isEmpty() || compilerFlavor == "unix"_L1) {
371 // traditional Unix compilers use both CPATH and CPLUS_INCLUDE_PATH
372 // $CPATH feeds to #include <...> and #include "...", whereas
373 // CPLUS_INCLUDE_PATH is equivalent to GCC's -isystem, so we parse later
374 const auto cpath = qgetenv("CPATH").split(QDir::listSeparator().toLatin1());
375 for (const QByteArray &p : cpath)
377 const auto cplus_include_path = qgetenv("CPLUS_INCLUDE_PATH").split(QDir::listSeparator().toLatin1());
378 for (const QByteArray &p : cplus_include_path)
380 } else if (compilerFlavor == "msvc"_L1) {
381 // MSVC uses one environment variable: INCLUDE
382 const auto include = qgetenv("INCLUDE").split(QDir::listSeparator().toLatin1());
383 for (const QByteArray &p : include)
385 } else {
386 error(qPrintable("Unknown compiler flavor '"_L1 + compilerFlavor +
387 "'; valid values are: msvc, unix."_L1));
388 parser.showHelp(1);
389 }
390
391 const auto macFrameworks = parser.values(macFrameworkOption);
392 for (const QString &path : macFrameworks) {
393 // minimalistic framework support for the mac
395 p.isFrameworkPath = true;
396 pp.includes += p;
397 }
398 const auto defines = parser.values(defineOption);
399 for (const QString &arg : defines) {
400 QByteArray name = arg.toLocal8Bit();
401 QByteArray value("1");
402 const qsizetype eq = name.indexOf('=');
403 if (eq >= 0) {
404 value = name.mid(eq + 1);
405 name = name.left(eq);
406 }
407 if (name.isEmpty()) {
408 error("Missing macro name");
409 parser.showHelp(1);
410 }
411 Macro macro;
413 macro.symbols.removeLast(); // remove the EOF symbol
414 pp.macros.insert(name, macro);
415 }
416 const auto undefines = parser.values(undefineOption);
417 for (const QString &arg : undefines) {
418 QByteArray macro = arg.toLocal8Bit();
419 if (macro.isEmpty()) {
420 error("Missing macro name");
421 parser.showHelp(1);
422 }
423 pp.macros.remove(macro);
424 }
425 const QStringList noNotesCompatValues = parser.values(noNotesWarningsCompatOption);
426 if (parser.isSet(noNotesOption) || noNotesCompatValues.contains("n"_L1))
427 moc.displayNotes = false;
428 if (parser.isSet(noWarningsOption) || noNotesCompatValues.contains("w"_L1))
429 moc.displayWarnings = moc.displayNotes = false;
430
431 if (autoInclude) {
432 qsizetype spos = filename.lastIndexOf(QDir::separator());
433 qsizetype ppos = filename.lastIndexOf(u'.');
434 // spos >= -1 && ppos > spos => ppos >= 0
435 moc.noInclude = (ppos > spos && filename.at(ppos + 1).toLower() != u'h');
436 }
437 if (defaultInclude) {
438 if (moc.includePath.isEmpty()) {
439 if (filename.size()) {
440 if (output.size())
441 moc.includeFiles.append(combinePath(filename, output));
442 else
443 moc.includeFiles.append(QFile::encodeName(filename));
444 }
445 } else {
446 moc.includeFiles.append(combinePath(filename, filename));
447 }
448 }
449
450 if (filename.isEmpty()) {
451 filename = QStringLiteral("standard input");
452 in.open(stdin, QIODevice::ReadOnly);
453 } else {
454 in.setFileName(filename);
455 if (!in.open(QIODevice::ReadOnly)) {
456 fprintf(stderr, "moc: %s: No such file\n", qPrintable(filename));
457 return 1;
458 }
459 moc.filename = filename.toLocal8Bit();
460 }
461
462 const auto metadata = parser.values(metadataOption);
463 for (const QString &md : metadata) {
464 qsizetype split = md.indexOf(u'=');
465 QString key = md.left(split);
466 QString value = md.mid(split + 1);
467
468 if (split == -1 || key.isEmpty() || value.isEmpty()) {
469 error("missing key or value for option '-M'");
470 } else if (key.indexOf(u'.') != -1) {
471 // Don't allow keys with '.' for now, since we might need this
472 // format later for more advanced meta data API
473 error("A key cannot contain the letter '.' for option '-M'");
474 } else {
475 QJsonArray array = moc.metaArgs.value(key);
477 moc.metaArgs.insert(key, array);
478 }
479 }
480
481 moc.currentFilenames.push(filename.toLocal8Bit());
482 moc.includes = pp.includes;
483
484 if (Q_UNLIKELY(parser.isSet(debugIncludesOption))) {
485 fprintf(stderr, "debug-includes: include search list:\n");
486
487 for (auto &includePath : pp.includes) {
488 fprintf(stderr, "debug-includes: '%s' framework: %d \n",
489 includePath.path.constData(),
490 includePath.isFrameworkPath);
491 }
492 fprintf(stderr, "debug-includes: end of search list.\n");
493 }
494
495 // 1. preprocess
496 const auto includeFiles = parser.values(includeOption);
497 QStringList validIncludesFiles;
498 for (const QString &includeName : includeFiles) {
499 QByteArray rawName = pp.resolveInclude(QFile::encodeName(includeName), moc.filename);
500 if (rawName.isEmpty()) {
501 fprintf(stderr, "Warning: Failed to resolve include \"%s\" for moc file %s\n",
502 includeName.toLocal8Bit().constData(),
503 moc.filename.isEmpty() ? "<standard input>" : moc.filename.constData());
504 } else {
505 QFile f(QFile::decodeName(rawName));
506 if (f.open(QIODevice::ReadOnly)) {
507 moc.symbols += Symbol(0, MOC_INCLUDE_BEGIN, rawName);
508 moc.symbols += pp.preprocessed(rawName, &f);
509 moc.symbols += Symbol(0, MOC_INCLUDE_END, rawName);
510 validIncludesFiles.append(includeName);
511 } else {
512 fprintf(stderr, "Warning: Cannot open %s included by moc file %s: %s\n",
513 rawName.constData(),
514 moc.filename.isEmpty() ? "<standard input>" : moc.filename.constData(),
515 f.errorString().toLocal8Bit().constData());
516 }
517 }
518 }
519 moc.symbols += pp.preprocessed(moc.filename, &in);
520
521 if (!pp.preprocessOnly) {
522 // 2. parse
523 moc.parse();
524 }
525
526 // 3. and output meta object code
527
529
530 bool outputToFile = true;
531 if (output.size()) { // output file specified
532#if defined(_MSC_VER)
533 if (_wfopen_s(&out, reinterpret_cast<const wchar_t *>(output.utf16()), L"w") != 0)
534#else
535 out = fopen(QFile::encodeName(output).constData(), "w"); // create output file
536 if (!out)
537#endif
538 {
539 fprintf(stderr, "moc: Cannot create %s\n", QFile::encodeName(output).constData());
540 return 1;
541 }
542
543 if (parser.isSet(jsonOption)) {
544 const QString jsonOutputFileName = output + ".json"_L1;
545 FILE *f;
546#if defined(_MSC_VER)
547 if (_wfopen_s(&f, reinterpret_cast<const wchar_t *>(jsonOutputFileName.utf16()), L"w") != 0)
548#else
549 f = fopen(QFile::encodeName(jsonOutputFileName).constData(), "w");
550 if (!f)
551#endif
552 fprintf(stderr, "moc: Cannot create JSON output file %s. %s\n",
553 QFile::encodeName(jsonOutputFileName).constData(),
554 strerror(errno));
555 jsonOutput.reset(f);
556 }
557 } else { // use stdout
558 out = stdout;
559 outputToFile = false;
560 }
561
562 if (pp.preprocessOnly) {
563 fprintf(out, "%s\n", composePreprocessorOutput(moc.symbols).constData());
564 } else {
565 if (moc.classList.isEmpty())
566 moc.note("No relevant classes found. No output generated.");
567 else
568 moc.generate(out, jsonOutput.data());
569 }
570
571 if (output.size())
572 fclose(out);
573
574 if (parser.isSet(depFileOption)) {
575 // 4. write a Make-style dependency file (can also be consumed by Ninja).
576 QString depOutputFileName;
577 QString depRuleName = output;
578
579 if (parser.isSet(depFileRuleNameOption))
580 depRuleName = parser.value(depFileRuleNameOption);
581
582 if (parser.isSet(depFilePathOption)) {
583 depOutputFileName = parser.value(depFilePathOption);
584 } else if (outputToFile) {
585 depOutputFileName = output + ".d"_L1;
586 } else {
587 fprintf(stderr, "moc: Writing to stdout, but no depfile path specified.\n");
588 }
589
591 FILE *depFileHandleRaw;
592#if defined(_MSC_VER)
593 if (_wfopen_s(&depFileHandleRaw,
594 reinterpret_cast<const wchar_t *>(depOutputFileName.utf16()), L"w") != 0)
595#else
596 depFileHandleRaw = fopen(QFile::encodeName(depOutputFileName).constData(), "w");
597 if (!depFileHandleRaw)
598#endif
599 fprintf(stderr, "moc: Cannot create dep output file '%s'. %s\n",
600 QFile::encodeName(depOutputFileName).constData(),
601 strerror(errno));
602 depFileHandle.reset(depFileHandleRaw);
603
604 if (!depFileHandle.isNull()) {
605 // First line is the path to the generated file.
606 fprintf(depFileHandle.data(), "%s: ",
607 escapeAndEncodeDependencyPath(depRuleName).constData());
608
609 QByteArrayList dependencies;
610
611 // If there's an input file, it's the first dependency.
612 if (!filename.isEmpty()) {
613 dependencies.append(escapeAndEncodeDependencyPath(filename).constData());
614 }
615
616 // Additional passed-in includes are dependencies (like moc_predefs.h).
617 for (const QString &includeName : validIncludesFiles) {
618 dependencies.append(escapeAndEncodeDependencyPath(includeName).constData());
619 }
620
621 // Plugin metadata json files discovered via Q_PLUGIN_METADATA macros are also
622 // dependencies.
623 for (const QString &pluginMetadataFile : moc.parsedPluginMetadataFiles) {
624 dependencies.append(escapeAndEncodeDependencyPath(pluginMetadataFile).constData());
625 }
626
627 // All pre-processed includes are dependnecies.
628 // Sort the entries for easier human consumption.
630 std::sort(includeList.begin(), includeList.end());
631
632 for (QByteArray &includeName : includeList) {
633 dependencies.append(escapeDependencyPath(includeName));
634 }
635
636 // Join dependencies, output them, and output a final new line.
637 const auto dependenciesJoined = dependencies.join(QByteArrayLiteral(" \\\n "));
638 fprintf(depFileHandle.data(), "%s\n", dependenciesJoined.constData());
639 }
640 }
641
642 return 0;
643}
644
646
647int main(int _argc, char **_argv)
648{
649 return QT_PREPEND_NAMESPACE(runMoc)(_argc, _argv);
650}
Definition moc.h:202
QList< IncludePath > includes
Definition parser.h:30
QSet< QByteArray > preprocessedIncludes
void setDebugIncludes(bool value)
Symbols preprocessed(const QByteArray &filename, QFile *device)
static bool preprocessOnly
QByteArray resolveInclude(const QByteArray &filename, const QByteArray &relativeTo)
static Symbols tokenize(const QByteArray &input, int lineNum=1, TokenizeMode mode=TokenizeCpp)
\inmodule QtCore
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
qsizetype length() const noexcept
Same as size().
Definition qbytearray.h:479
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
QByteArray mid(qsizetype index, qsizetype len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos.
QChar toLower() const noexcept
Returns the lowercase equivalent if the character is uppercase or titlecase; otherwise returns the ch...
Definition qchar.h:448
The QCommandLineOption class defines a possible command-line option. \inmodule QtCore.
void setDescription(const QString &description)
Sets the description used for this option to description.
void setFlags(Flags aflags)
Set the set of flags that affect this command-line option to flags.
void setValueName(const QString &name)
Sets the name of the expected value, for the documentation, to valueName.
The QCommandLineParser class provides a means for handling the command line options.
QString value(const QString &name) const
Returns the option value found for the given option name optionName, or an empty string if not found.
void addPositionalArgument(const QString &name, const QString &description, const QString &syntax=QString())
Defines an additional argument to the application, for the benefit of the help text.
QStringList positionalArguments() const
Returns a list of positional arguments.
void setSingleDashWordOptionMode(SingleDashWordOptionMode parsingMode)
Sets the parsing mode to singleDashWordOptionMode.
QStringList values(const QString &name) const
Returns a list of option values found for the given option name optionName, or an empty list if not f...
void setApplicationDescription(const QString &description)
Sets the application description shown by helpText().
bool addOption(const QCommandLineOption &commandLineOption)
Adds the option option to look for while parsing.
Q_NORETURN void showHelp(int exitCode=0)
Displays the help information, and exits the application.
bool isSet(const QString &name) const
Checks whether the option name was passed to the application.
void process(const QStringList &arguments)
Processes the command line arguments.
QCommandLineOption addVersionOption()
Adds the {-v} / {–version} option, which displays the version string of the application.
QCommandLineOption addHelpOption()
Adds help options to the command-line parser.
\inmodule QtCore
static void setApplicationVersion(const QString &version)
static QStringList arguments()
static QDir current()
Returns the application's current directory.
Definition qdir.h:216
static QChar separator()
Returns the native directory separator: "/" under Unix and "\\" under Windows.
Definition qdir.h:206
QString absolutePath() const
Returns the absolute path (a path that starts with "/" or with a drive specification),...
Definition qdir.cpp:667
QString relativeFilePath(const QString &fileName) const
Returns the path to fileName relative to the directory.
Definition qdir.cpp:843
static constexpr QChar listSeparator() noexcept
Definition qdir.h:197
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
QString absoluteFilePath() const
Returns an absolute path including the file name.
QDir dir() const
Returns the path of the object's parent directory as a QDir object.
QString filePath() const
Returns the file name, including the path (which may be absolute or relative).
\inmodule QtCore
Definition qfile.h:93
static QByteArray encodeName(const QString &fileName)
Converts fileName to an 8-bit encoding that you can use in native APIs.
Definition qfile.h:158
static QString decodeName(const QByteArray &localFileName)
This does the reverse of QFile::encodeName() using localFileName.
Definition qfile.h:162
bool remove(const Key &key)
Removes the item that has the key from the hash.
Definition qhash.h:956
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1283
\inmodule QtCore\reentrant
Definition qjsonarray.h:18
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void removeLast() noexcept
Definition qlist.h:808
\inmodule QtCore
T * data() const noexcept
Returns the value of the pointer referenced by this object.
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
QList< T > values() const
Definition qset.h:297
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.h:279
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
const ushort * utf16() const
Returns the QString as a '\0\'-terminated array of unsigned shorts.
Definition qstring.cpp:6737
static QString fromLocal8Bit(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5788
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1101
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString & insert(qsizetype i, QChar c)
Definition qstring.cpp:3110
QByteArray toLocal8Bit() const &
Definition qstring.h:567
QString & append(QChar c)
Definition qstring.cpp:3227
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
Definition qstring.cpp:5161
QString & remove(qsizetype i, qsizetype len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition qstring.cpp:3435
QString & prepend(QChar c)
Definition qstring.h:411
qsizetype length() const
Returns the number of characters in this string.
Definition qstring.h:187
int collectJson(const QStringList &jsonFiles, const QString &outputFile, bool skipStdIn)
StringType escapeDependencyPath(const StringType &path)
static QByteArray escapeAndEncodeDependencyPath(const QString &path)
int main()
[0]
QList< QVariant > arguments
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
@ mocOutputRevision
#define QByteArrayLiteral(str)
Definition qbytearray.h:52
#define Q_UNLIKELY(x)
DBusConnection const char DBusError * error
static const char includeList[]
static QString moc(const QString &name)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLuint64 GLenum void * handle
GLuint64 key
GLfloat GLfloat f
GLuint name
GLenum array
GLuint in
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
static void split(QT_FT_Vector *b)
SSL_CTX int(*) void arg)
#define qPrintable(string)
Definition qstring.h:1391
#define QStringLiteral(str)
static QByteArray combinePath(const QString &infile, const QString &outfile)
Definition main.cpp:39
static bool hasNext(const Symbols &symbols, int i)
Definition main.cpp:66
int runMoc(int argc, char **argv)
Definition main.cpp:158
static QStringList argumentsFromCommandLineAndFile(const QStringList &arguments, bool &hasOptionFiles)
Definition main.cpp:126
QByteArray composePreprocessorOutput(const Symbols &symbols)
Definition main.cpp:73
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
ptrdiff_t qsizetype
Definition qtypes.h:70
QT_BEGIN_NAMESPACE typedef uchar * output
QT_END_NAMESPACE typedef QT_PREPEND_NAMESPACE(quintptr) WId
QTextStream out(stdout)
[7]
QStringList files
[8]
QApplication app(argc, argv)
[0]
QDBusArgument argument
Symbols symbols
bool isVariadic
bool isFunction
Symbols arguments
static void cleanup(FILE *handle)
Definition main.cpp:63
Token token
Definition symbols.h:91
int lineNum
Definition symbols.h:90
QByteArray lexem() const
Definition symbols.h:92
Token
Definition token.h:194
@ PP_NEWLINE
Definition token.h:224
@ PP_STRING_LITERAL
Definition token.h:238
@ PP_IDENTIFIER
Definition token.h:216
@ PP_WHITESPACE
Definition token.h:240
@ PP_NOTOKEN
Definition token.h:225