1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "runqttool.h"
5#include "fmt.h"
6
7#include "profileutils.h"
8
9#include <QtCore/qcoreapplication.h>
10#include <QtCore/qdir.h>
11#include <QtCore/qregularexpression.h>
12
13#include <cstdlib>
14#include <iostream>
15
16#ifdef Q_OS_UNIX
17#include <sys/wait.h>
18#endif
19
20static QString qtToolFilePath(const QString &toolName, QLibraryInfo::LibraryPath location)
21{
22 QString filePath = QLibraryInfo::path(p: location) + QLatin1Char('/') + toolName;
23#ifdef Q_OS_WIN
24 filePath.append(QLatin1String(".exe"));
25#endif
26 return QDir::cleanPath(path: filePath);
27}
28
29static void rtPrintErr(const QString &out)
30{
31 std::cerr << qUtf8Printable(out);
32}
33
34static QString shellQuoted(const QString &str)
35{
36 static QRegularExpression rx(QStringLiteral("\\s"));
37 QString result = str;
38 if (result.contains(re: rx)) {
39 const QLatin1Char dblqt = QLatin1Char('"');
40 result.prepend(c: dblqt);
41 result.append(c: dblqt);
42 }
43 return result;
44}
45
46static QStringList shellQuoted(const QStringList &strs)
47{
48 QStringList result;
49 result.reserve(asize: strs.size());
50 std::transform(first: strs.begin(), last: strs.end(), result: std::back_inserter(x&: result),
51 unary_op: static_cast<QString (*)(const QString &)>(&shellQuoted));
52 return result;
53}
54
55static QString commandLineForSystem(const QString &program,
56 const QStringList &arguments)
57{
58 return shellQuoted(str: program)
59 + QLatin1Char(' ')
60 + shellQuoted(strs: arguments).join(sep: QLatin1Char(' '));
61}
62
63void runQtTool(const QString &toolName, const QStringList &arguments,
64 QLibraryInfo::LibraryPath location)
65{
66 int exitCode = 0;
67 const QString commandLine = commandLineForSystem(program: qtToolFilePath(toolName, location), arguments);
68#if defined(Q_OS_WIN)
69 exitCode = _wsystem(reinterpret_cast<const wchar_t *>(commandLine.utf16()));
70#elif defined(Q_OS_UNIX)
71 int ret = std::system(qPrintable(commandLine));
72 exitCode = WEXITSTATUS(ret);
73#else
74 exitCode = std::system(qPrintable(commandLine));
75#endif
76 if (exitCode != 0)
77 exit(status: exitCode);
78}
79
80void runInternalQtTool(const QString &toolName, const QStringList &arguments)
81{
82 runQtTool(toolName, arguments, location: QLibraryInfo::LibraryExecutablesPath);
83}
84
85std::unique_ptr<QTemporaryFile> createProjectDescription(QStringList args)
86{
87 std::unique_ptr<QTemporaryFile> file(new QTemporaryFile(QStringLiteral("XXXXXX.json")));
88 if (!file->open()) {
89 rtPrintErr(out: FMT::tr(sourceText: "Cannot create temporary file: %1\n").arg(a: file->errorString()));
90 exit(status: 1);
91 }
92 file->close();
93 args << QStringLiteral("-out") << file->fileName();
94 runInternalQtTool(QStringLiteral("lprodump"), arguments: args);
95 return file;
96}
97

source code of qttools/src/linguist/shared/runqttool.cpp